1.基础
预定义宏
- C标准兼容宏定义
- 常用宏
- __func__
返回所在函数的名字- 在结构体的构造函数中,初始化成员列表使用__func__预定义标识符是可行的,其效果跟在函数中使用一样。
- 不过将__fun__标识符作为函数参数的默认值是不允许的,如下例所示:
这是由于在参数声明时,__func__还未被定义。void FuncFail( string func_name = __func__) {};// 无法通过编译
- _Pragma
_Pragma操作符的格式如下所示:_Pragma (字符串字面量)
- 头文件只被编译一次
#pragma once #ifndef THIS_HEADER #define THIS_HEADER // 一些头文件的定义 #endif _Pragma("once");
- 头文件只被编译一次
- __VA_ARGS__
变长参数的宏定义是指在宏定义中参数列表的最后一个参数为省略号,而预定义宏__VA_ARGS__则可以在宏定义的实现部分替换省略号所代表的字符串。比如:#define PR(...) printf(__VA_ARGS__) #define LOG(...) {\ fprintf(stderr,"%s: Line %d:\t", __FILE__, __LINE__);\ fprintf(stderr, __VA_ARGS__);\ fprintf(stderr,"\n");\ }
- __cplusplus
由于extern "C"可以抑制C++对函数名、变量名等符号(symbol)进行名称重整(name mangling),因此编译出的C目标文件和C++目标文件中的变量、函数名称等符号都是相同的(否则不相同),链接器可以可靠地对两种类型的目标文件进行链接。这样该做法成为了C与C++混用头文件的典型做法。#ifdef __cplusplus extern "C" { #endif // 一些代码 #ifdef __cplusplus } #endif
使得不支持C++11的代码编译立即报错并终止编译。#if __cplusplus < 201103L #error "should use C++11 implementation" #endif
- 静态断言
利用“除0”会导致编译器报错这个特性来实现静态断言。
static_assert的断言表达式的结果必须是在编译时期可以计算的表达式,即必须是常量表达式。如果读者使用了变量,则会导致错误#define assert_static(e) \ do { \ enum { assert_static__ = 1/(e) }; \ } while (0)
- __func__
- 修饰符