C++ 预定义的宏

示例

预定义的宏是编译器定义的宏(与源文件中的用户定义相反)。这些宏不得由用户重新定义或取消定义。

以下宏是C ++标准预定义的:

  • __LINE__包含使用此宏的行的行号,并且可以通过#line伪指令进行更改。

  • __FILE__包含使用此宏的文件的文件名,并且可以通过#line伪指令进行更改。

  • __DATE__包含"Mmm dd yyyy"文件编译的日期(格式),其中Mmm的格式类似于通过调用获得的格式。std::asctime()

  • __TIME__包含"hh:mm:ss"文件编译的时间(格式)。

  • __cplusplus由(合格)C ++编译器在编译C ++文件时定义。它的值是编译器完全符合的标准版本,即199711L对于C ++ 98和C ++ 03,201103L对于C ++ 11和201402L对于C ++ 14标准。

C ++ 11
  • __STDC_HOSTED__被定义为1如果实现托管,或者0如果它是独立的

C ++ 17
  • __STDCPP_DEFAULT_NEW_ALIGNMENT__包含一个size_t文字,它是用于调用alignment-unware的对齐方式operator new。

此外,实现允许预定义以下宏,并且可能存在也可能不存在:

  • __STDC__具有与实现相关的含义,通常仅在将文件编译为C时定义,以表示完全符合C标准。(或者,如果编译器决定不支持此宏,则永远不会。)

C ++ 11
  • __STDC_VERSION__具有与实现相关的含义,其值通常是C版本,类似于__cplusplusC ++版本。(或者,如果编译器决定不支持此宏,则甚至没有定义。)

  • __STDC_MB_MIGHT_NEQ_WC__定义为1,如果基本字符集的窄编码的值可能不等于其宽对应字符的值(例如(uintmax_t)'x' != (uintmax_t)L'x')

  • __STDC_ISO_10646__定义为如果wchar_t将其编码为Unicode,并以形式扩展为一个整数常量yyyymmL,指示支持的最新Unicode版本。

  • __STDCPP_STRICT_POINTER_SAFETY__定义为1,如果实现具有严格的指针安全性(否则它具有宽松的指针安全性

  • __STDCPP_THREADS__定义为1,如果程序可以具有多个执行线程(适用于独立实现,则托管实现始终可以具有多个线程)

还值得一提的是__func__,它不是宏,而是预定义的函数局部变量。它包含使用的函数名称,以实现定义的格式作为静态字符数组。

在这些标准的预定义宏之上,编译器可以具有自己的预定义宏集。必须参考编译器文档来学习这些内容。例如:

  • 海湾合作委员会

  • Microsoft Visual C ++

  • 英特尔C ++编译器

一些宏仅用于查询对某些功能的支持:

#ifdef __cplusplus // 如果由C ++编译器编译
extern "C"{ // 必须装饰C代码
   // 这里的C库头声明
}
#endif

其他对于调试非常有用:

C ++ 11
bool success = doSomething( /*some arguments*/ );
if( !success ){
    std::cerr << "ERROR: doSomething() failed on line " << __LINE__ - 2
              << " 在功能上 " << __func__ << "()"
              << " 在文件中 " << __FILE__
              << std::endl;
}

和其他一些琐碎的版本控制:

int main( int argc, char *argv[] ){
    if( argc == 2 && std::string( argv[1] ) == "-v" ){
        std::cout << "Hello World program\n"
                  << "v 1.1\n" // 我必须记得手动更新
                  << "compiled: " << __DATE__ << ' ' << __TIME__ // 这会自动更新
                  << std::endl;
    }
    else{
        std::cout << "Hello World!\n";
    }
}