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

时间:2015-04-03 13:48:45

标签: c++ c-preprocessor

我试图更详细地了解C ++编译过程,所以我试着看看C ++预处理器的结果如何:

#include <iostream>

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

g++ -E main.cpp > preprocessed

运行仅预处理器

输出是一个非常长的文件,因为<iostream>标题随着它包含的所有内容而扩展。但是,文件的结尾如下所示:

...
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;
}

预计评论会消失,但预处理器会在以#开头的行上添加一些信息。

行是否以#cile 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

生成相同的可执行文件。

1 个答案:

答案 0 :(得分:3)

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

  • 在相应的行生成错误信息
  • 生成与行号
  • 链接的调试信息

这些被称为行标记

此上下文中的#不是合法的C ++代码,因为它表示预处理程序指令。但由于该文件已经过预处理,我们知道它并不意味着,所以它在预处理的输出文件中被重用,用于上述目的。

您可以使用-P选项删除这些内容。从手册页:

  

-P禁止在预处理器的输出中生成线标记。当对非C (sic)代码运行预处理器时,这可能很有用,并且会被发送到可能被行标记混淆的程序。

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