预定义的宏

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

以下宏由 C++标准预定义:

  • __LINE__ 包含此宏使用的行的行号,可以通过 #line 指令进行更改。
  • __FILE__ 包含此宏使用的文件的文件名,可以通过 #line 指令进行更改。
  • __DATE__ 包含文件编译的日期(采用 Mmm dd yyyy 格式),其中 Mmm 的格式就像通过调用 std::asctime() 获得的那样。
  • __TIME__ 包含文件编译的时间(以 hh:mm:ss 格式)。
  • __cplusplus 由(符合)C++编译器在编译 C++文件时定义。它的值是编译器完全符合的标准版本,即用于 C++ 98 和 C++ 03 的 199711L,用于 C++ 11 的 201103L 和用于 C++ 14 标准的 201402L

Version >= C++ 11

  • 如果实现是托管的,则 __STDC_HOSTED__ 定义为 1 ,如果是独立的,则定义为 0

Version >= C++ 17

  • __STDCPP_DEFAULT_NEW_ALIGNMENT__ 包含一个 size_t 文字,这是用于调整对齐 - 不知道 operator new 的对齐方式。

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

  • __STDC__ 具有依赖于实现的含义,通常仅在将文件编译为 C 时定义,以表示完全符合 C 标准。 (或者从不,如果编译器决定不支持这个宏。)

Version >= C++ 11

  • __STDC_VERSION__ 具有依赖于实现的含义,其值通常是 C 版本,类似于 __cplusplus 是 C++版本。 (如果编译器决定不支持此宏,则甚至不定义。)
  • __STDC_MB_MIGHT_NEQ_WC__ 定义为 1,如果基本字符集的窄编码的值可能不等于其宽对应的值(例如,如果 (uintmax_t)'x' != (uintmax_t)L'x'
  • 如果 wchar_t 编码为 Unicode,则定义 __STDC_ISO_10646__,并以 yyyymmL 的形式扩展为整数常量,表示支持的最新 Unicode 版本。
  • __STDCPP_STRICT_POINTER_SAFETY__ 定义为 1,如果实现具有严格的指针安全性 (否则它已经放松了指针安全性
  • __STDCPP_THREADS__ 定义为 1,如果程序可以有多个执行线程(适用于独立实现 - 托管实现总是可以有多个线程)

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

除了那些标准的预定义宏之外,编译器还可以拥有自己的一组预定义宏。必须参考编译器文档来学习它们。例如:

一些宏只是为了查询某些功能的支持:

#ifdef __cplusplus // if compiled by C++ compiler
extern "C"{ // C code has to be decorated
   // C library header declarations here
}
#endif

其他对调试非常有用:

Version >= C++ 11

bool success = doSomething( /*some arguments*/ );
if( !success ){
    std::cerr << "ERROR: doSomething() failed on line " << __LINE__ - 2
              << " in function " << __func__ << "()"
              << " in file " << __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" // I have to remember to update this manually
                  << "compiled: " << __DATE__ << ' ' << __TIME__ // this updates automagically
                  << std::endl;
    }
    else{
        std::cout << "Hello World!\n";
    }
}