# 在预处理的 C++ 代码中的含义是什么?

What is the meaning of # in preprocessed C++ code?

我想更详细地了解 C++ 编译过程,所以我试着看看 C++ pre-processor 的结果如何:

#include <iostream>

int main()
{
    // I am a comment!
    std::cout << "Hi!" << std::endl;
    return 0;
}

然后我运行:

g++ -E main.cpp > preprocessed

到运行只是预处理器

输出是一个很长的文件,因为 <iostream> header 连同它包含的所有内容都被扩展了。然而,文件的结尾看起来像这样:

...
namespace std __attribute__ ((__visibility__ ("default")))
{

# 60 "/usr/include/c++/4.9/iostream" 3
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;


  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;




  static ios_base::Init __ioinit;


}
# 2 "main.cpp" 2

int main()
{

    std::cout << "Hi!" << std::endl;
    return 0;
}

正如所料,注释消失了,但预处理器 在以 #.

开头的行上添加了一些信息

是否以 # 合法 C++ 开头的行?我认为 # 的唯一目的是指定预处理器指令。我认为 # 是一种指定评论的深奥方式,但是这段代码:

#include <iostream>

int main()
{
    # I am something that follows the hash symbol.
    std::cout << "Hi!" << std::endl;
    return 0;
}

不编译。


编辑:

显然 # 符号在函数范围之外是可以的:

g++ -E main.cpp > preprocessed.cpp
g++ preprocessed.cpp -o preprocessed

生成相同的可执行文件。

经过预处理的 C++ 代码包含以 # 开头的行,用于向编译器传达原始行号和函数调用信息,因此它可以:

  • 在适当的行产生错误信息
  • 生成与行号链接的调试信息

这些称为 行标记

A # 在此上下文中不是合法的 C++ 代码,因为它表示预处理器指令。但由于该文件已经过预处理,我们知道这不是那个意思,因此出于上述目的在预处理后的输出文件中重复使用它。

您可以使用 -P 选项摆脱这些。来自手册页:

-P Inhibit generation of linemarkers in the output from the preprocessor. This might be useful when running the preprocessor on something that is not C (sic) code, and will be sent to a program which might be confused by the linemarkers.

请注意,虽然手册页引用的是 C 代码而不是 C++ 代码(因为手册页在这方面对于 g++gcc 是相同的),但同样的考虑适用。