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);申明。

相关文章
相关标签/搜索