6

我有 2 个文件作为 qwe.h

#ifndef QWE_H
#define QWE_H
//#include <iostream>
int asd();
#endif

qwe.cc

#include "qwe.h"
int asd()
{
std::cout<<"asdasd";
}

仅运行预处理器g++ -E qwe.cpp > op4 给出以下输出

# 1 "qwe.cpp"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "qwe.cpp"
# 1 "qwe.h" 1




int asd();
# 2 "qwe.cpp" 2
int asd()
{
 std::cout<<"asdasd";
}

预处理器输出不应该是有效的C /C++ 文件吗?语句“# int string int”是什么意思

4

3 回答 3

6

它们是用于跟踪文件包含在其他文件中的位置的行号,这在生成编译器警告和错误时很有用。

请参阅维基百科上的这篇文章

于 2013-07-08T12:55:59.157 回答
5

GCC 做出了合理的努力来使预处理器输出转储仍然是有效的源代码。但一般的答案是否定的,它不是为了这个目的。

您还可以传递该-P选项-E以使其更具机器可读性,而人类可读性更低。更多的空白将被剥离,# 234 "blah.h"标记将不会出现。

预处理器输出不应该是有效的 c/c++ 文件吗?

预处理器所做的很大一部分是词法分析,或将源划分为标记。然后它扩展宏,根据特定规则生成标记和空格。宏可以生成不被空格分隔的标记。根据标准,直接呈现为文本的预处理器输出通常不可能重新划分为正确的标记。

GCC 加倍努力,试图通过引入更多的空格来满足预处理器输出可以表示为文本的期望,但这并不是一个真正值得依赖的好东西,当然也不能移植到其他编译器。

于 2013-07-08T13:00:42.650 回答
0

预处理器输出没有语言要求是有效的 C++——甚至预处理器的输出可用。但是 g++ 通常使用的预处理器(也许总是?)生成的输出本身可以编译为 C++。

语句的含义是什么# int string int

任何以 开头的行#都是预处理指令。如果后面的记号#未被识别,则后面的行部分#是非指令的。(尽管名称如此,非指令是预处理指令。)非指令通常被忽略。

通常它是处理所有预处理指令的预处理器,包括非指令,但在这种情况下,一些以开头的行#被传递给编译器,它知道忽略它们。

您可以通过将预处理器输出提供给编译器来证明这一点:

g++ -E foo.cpp > foo_preprocessed.cpp
g++ -c foo_preprocessed.cpp

如果foo.cpp有预处理器指令,特别是#include指令,foo-preprocessed.cpp可能会更大——但编译器仍然能够处理它。

语言标准根据标记而不是 tex 定义预处理器输出,但它允许足够的灵活性,以便文本是表示所需标记序列的有效方式。

(所有这些都适用于 C 以及 C++。)

于 2016-04-30T00:33:14.077 回答