cpp之宏和函數調用約定

宏定義

宏中的#和##

首先知道理解c中的鄰近字符串鏈接原則,即相鄰兩個字符串連接起來組成一個字符串。
printf("L" "java/lang/Object;""\n");是合法的而且輸出結果是Ljava/lang/Object;java

#define LOG(NAME, VALUE) log_info("the value of " #NAME " is :", VALUE)函數

#NAME會把傳入的參數名當成字符串處理.net

##將##兩邊的字符連在一塊兒做爲一個標識符code

#define VAR_N(name,n) name##nblog

VAR_N(age,1) -> age1字符串

宏的反作用

問題

#define MIN(A,B) ((A) <= (B) ? (A) : (B)) 若是代入++ --類型的參數會致使++ --被屢次執行產生反作用。好比:get

int i=0; int j=10;
 int c = MIN(i++,j++);

會被展開爲 ((i++) <= (j++) ? (i++) : (j++)) 最終致使返回的結果: i=2,j=11,c=1 從而產生反作用(i++執行了兩次,而且結果不正確本應爲0)。編譯器

解決

使用語句表達式消除反作用字符串處理

#define min(x, y) ({ const typeof(x) _x = (x); \
 const typeof(y) _y = (y); \
 (void) (&_x == &_y); \
 _x < _y ? _x : _y; \
 })

方法名修飾(Decorated Name)規則和函數調用約定

C編譯器的函數名修飾規則

  • __stdcall調用約定:io

    編譯器和連接器會在輸出函數名前加上一個下劃線前綴,函數名後面加上一個「@」符號和其參數的字節數,例如_functionname@number。
  • __cdecl調用約定:

    僅在輸出函數名前加上一個下劃線前綴,例如_functionname。
  • __fastcall調用約定:

    在輸出函數名前加上一個「@」符號,後面也是一個「@」符號和其參數的字節數,例如@functionname@number 。

C++編譯器的函數名修飾規則

參考

cpp與c交叉調用

cpp調用c:頭文件以下聲明,cpp文件引用頭文件。

#ifdef __cplusplus
extern "C" {
#endif
void show(PERSON* person);
#ifdef __cplusplus
}
#endif

c調用cpp: 頭文件按照上面的方式,cpp實現中引用頭文件,c調用文件中添加extern void show(PERSON* person);申明。

相關文章
相關標籤/搜索