#if #ifdef #if defined 等幾種常用的預處理指令的區別
技術標籤:unity
在寫shader時經常會出現一些預編譯指令比如 #if #ifdef #if defined 等,有的時候會感到困惑,所以決定仔細查一下具體的使用方法,並做一個簡單的測試。
#define
#define 指令用於定義一個巨集或者常量
#define 有兩種常用的格式:
- #define identifier token-string 定義一個巨集,在預編譯時會把所有identifier替換成token-string,可以用更容易理解的名稱去代替一個常量,例如:#define PI 3.1415926
- #define identifier( argument0, ..., argumentN-1 ) token-string 定義一個類似函式一樣的巨集,例如:#define AREA(area, w, h) (area = w*h);
// #define 的使用 //
#define SOME_MACRO
#define PI 3.141593
定義巨集時使用第一種方式,當沒有指定 token-string 時,需要注意的兩點是:
- 這個identifier依然是被定義了的,且可以使用#if defined 或 #ifdef 檢測到的
- 所有identifier字元都會被移除,或者理解為所有identifier的地方都被替換成空字串。
詳細資訊可以參考 #define文件
#if
#if 是一個預處理指令,用來控制原始檔中哪一部分會被編譯。
格式是: #if condition
簡單來說就是 #if 後面的條件語句(condition)如果執行結果不為0,則該#if語句塊內的程式碼會被編譯,否則就不會被編譯。
// #if 的使用 //
#define SOME_MACRO 0
#if SOME_MACRO
return float4(1,1,1,1);
#else
return float4(0,0,0,1);
#endif
以上程式碼結果返回黑色
// #if 的使用 // #define SOME_MACRO #if SOME_MACRO return float4(1,1,1,1); #else return float4(0,0,0,1); #endif
以上程式碼會報錯: invalid or unsupported integer constant expression
詳細資訊可以參考 #if文件
#ifdef
#ifdef 用於判斷一個常量或者巨集是否被定義
格式是: #ifdef identifier
identifier是一個巨集或者常量,可以通過#define指令來定義,如果identifier被定義過,則#ifdef 語句塊內的程式碼會被編譯,否則不會被編譯。
#ifdef 只是判斷一個常量或者巨集是否被定義,不可以用於表示式判斷,但是#if可以,例如:
#define CONST_VALUE 3
#if CONST_VALUE > 1
return float4(1,1,1,1);
#else
return float4(0,0,0,1);
#endif
#ifdef CONST_VALUE > 1 // 這樣寫會報錯 //
hlsl文件上的說法是#ifdef這種寫法只是為了相容以往版本,建議使用defined來判斷,即使用 #if defined(MACRO) 這種形式,接下來就會說到。
These directives are provided only for compatibility with previous versions of the language. The use of the defined operator with the #if directive is preferred.
詳細資訊可以參考 #ifdef文件
#if defined
這是文件裡更推薦的一種寫法
#if defined 和 #ifdef 都可以用來判斷一個巨集是否被定義,#if !defined 等同於 #ifndef。
#define SOME_MACRO
// #if defined 的使用 //
#if defined(SOME_MACRO)
// do something //
#elif defined(OTHER_MACRO)
// do something else //
#endif
// #ifdef 的使用 //
#ifdef SOME_MACRO
// do something //
#endif
#ifdef OTHER_MACRO
// do something else //
#endif
總結
- 如果是根據一個巨集是否被定義來決定一段程式碼要不要執行,建議使用 #if defined(MACRO) 方式
- 如果是根據一個表示式的值是否為0來決定一段程式碼要不要執行,建議使用 #if condition 方式
- #ifdef 用於判斷巨集或者常量是否被定義,不用於判斷表示式,#if 可以用於判斷表示式
作者:上午八點
連結:https://www.jianshu.com/p/5b763006b61e
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。