预处理器输出文件是否是有效的C / C ++文件

时间:2013-07-08 12:50:13

标签: c++ c-preprocessor

我有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”

的含义是什么

3 个答案:

答案 0 :(得分:6)

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

请参阅维基百科上的this article

答案 1 :(得分:5)

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

您还可以将-P选项与-E一起传递,以使其更具机器可读性,并且人性化程度较低。将删除更多的空格,并且不会显示# 234 "blah.h"标记。

  

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

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

GCC通过引入更多的空白来尽量满足预期处理器输出可以表示为文本的期望,但依靠它并不是一件好事,当然也不能移植到其他编译器。

答案 2 :(得分:0)

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

  

陈述# int string int的含义是什么?

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

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

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

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

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

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

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