語法鹽(英語:syntactic salt)是指在計算機語言中為了降低程式設計師撰寫出不良程式碼的設計,但其中仍會有潛藏錯誤存在的可能。例如,C語言或C++語言中Switch指令英語switch statementcase中若不加break編譯器並不會產生錯誤訊息,部分程式設計師認為宣告變數型態也是語法鹽的一種。

語法鹽的例子

C++

相較於 C 中形如 (T)v 的 C 樣式轉換和 T(v) 的函式樣式轉換,C++ 通過引入 static_cast、reinterpret_cast、const_cast 和 dynamic_cast 這四種轉換來強迫程式設計師多敲鍵盤,從而令他們少用轉換。[來源請求]

double  d =0.1;
const int i=static_cast<int>(d);//静态转换:编译时能进行类型检查的转换
void *pv=reinterpret_cast<void*>(i);//重解释转换:在不兼容的类型间进行转换(例如指针与非指针)
const int *pi=&i;
int *pi2=const_cast<int*>(pi);//常量转换:去掉 const、volatile 等修饰符
class C{
    public:
    virtual ~C(){};
};
class D: pub lic C{};
D d;
const C &rc=d;
const D &rd=dynamic_cast<const D &>(rc);//动态转换:在类继承体系里上下转换,因必须在编译时检查(RTTI)而得名

Java

Java中並不允許將一個宣告為float類型的變數賦值給一個宣告為int類型的變數,但是CC++會自動把float類型的變數捨去小數並賦值給int類型的變數。

int num1;
float pi=3.14159;
num1=pi;  //賦值錯誤

C#

C#中,如果要隱藏一個繼承的成員函式,需加上new關鍵字來說明該成員函式是隱藏的,即便不使用new關鍵字來說明隱藏也能通過編譯產生隱藏效果,但仍會產生編譯警告[1]

public class BaseC
{
    public int x;
    public void Invoke() { }
}
public class DerivedC : BaseC
{
    new public void Invoke() { } //隱藏繼承自BaseC的Invoke()成員函數
}

C#在switch語法中的case標記代碼塊內,如果沒有gotoreturnthrow跳離語法,一定得加上break語法[2]

switch (caseSwitch)
{
    case 1:
        Console.WriteLine("Case 1...");
        //在此撰寫break或其他跳離語法,否則將產生編譯錯誤
    case 2:
        Console.WriteLine("... and/or Case 2");
        break;
}

總結

語法鹽有可能會違背它的初衷,使程式碼可讀性降低或浪費程式碼的空間占用。在極端條件下,真正有用的程式碼可能要比為了滿足語法鹽要求而增加的程式碼還要短。另外一種替代語法鹽的方法是在程式碼可能產生錯誤時,讓編譯器產生警告——這也是C和C++的編譯器常見的作法。

參考文獻

  1. ^ new Modifier (C# Reference) - Visual Studio 2012. [2014-02-04]. (原始內容存檔於2014-02-09). 
  2. ^ switch (C# Reference) - Visual Studio 2012. [2014-02-04]. (原始內容存檔於2014-02-04). 

延伸閱讀

參閱

外部連結