【问题标题】:What is the meaning of # in preprocessed C++ code?# 在预处理的 C++ 代码中是什么意思?
【发布时间】:2015-04-03 13:48:45
【问题描述】:

我正在尝试更详细地了解 C++ 编译过程,因此我尝试查看 C++ 预处理器的结果如何:

#include <iostream>

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

然后我跑了:

g++ -E main.cpp > preprocessed

只运行预处理器

输出是一个很长的文件,因为 &lt;iostream&gt; 标头连同它包含的所有内容都被扩展了。但是,文件的结尾是这样的:

...
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++ c-preprocessor


【解决方案1】:

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

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

这些被称为线标记

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

您可以使用-P 选项来消除这些问题。从手册页:

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

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

【讨论】:

    猜你喜欢
    • 2017-03-18
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多