【发布时间】: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
只运行预处理器。
输出是一个很长的文件,因为 <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;
}
出乎意料的是,注释消失了,但预处理器在以#开头的行中添加了一些信息。
以 # 开头的行是否合法 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
生成相同的可执行文件。
【问题讨论】:
-
它设置以下代码段来自的文件和行号偏移量,以正确获取错误消息。
-
FWIW,你可以用 -E -P 编译去掉它们。
-
AFAICT,C++ 标准定义了逻辑编译步骤,但这些步骤之间的中间表示的格式是实现定义的,因此它本身不必是“合法的”C++。
-
@AndréCaron 这不是实现定义的
标签: c++ c-preprocessor