gpt4 book ai didi

c++ - 交叉文件 #if 和 #endif - 它应该合法吗?

转载 作者:太空狗 更新时间:2023-10-29 20:21:59 24 4
gpt4 key购买 nike

根据C11标准,

A preprocessing directive of the form

# include "q-char-sequence" new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters.

所以如果我有一个头文件 test.h 包含:

#endif

还有一个源文件 test.c 包含:

#if 1
#include "test.h"

原地替换test.h的内容,不应该按照标准通过预处理阶段吗?

但我不能用 clang 做到这一点,它说:

In file included from test.c:2:
./test.h:1:2: error: #endif without #if
#endif
^
test.c:1:2: error: unterminated conditional directive
#if 1
^
2 errors generated.

那么标准规定的行为是什么?

最佳答案

如果您阅读例如this C++ #include reference包含的文件首先运行 translation phases一到四,和phase four正在运行预处理器(递归)。

这意味着您包含的文件在 #if#endif 方面必须是完整的。

这在 C 中也会发生。


在阅读了 C11 规范(ISO/IEC 9899:2011 [2012])后,我认为是这样的:

编译器处于预处理器阶段 (phase 4) 并计算 #if 1 预处理器指令。条件评估为真,因此它进入条件内的 block 。可以看到 #include "test.h" 指令。

当编译器处理 include 指令时,它会暂时停止处理当前文件,以处理包含的文件。在继续处理当前源文件之前,对包含文件的处理会经过编译阶段 1 到 4(含)。

当包含头文件本身的处理进入阶段 4 并开始处理 #endif 指令时,它不会在递归包含中up stack 找到匹配的#if,预处理器只查看当前堆栈帧(当前文件)。因此,您会收到关于没有 #if 的第一个错误。该标准实际上对此没有任何说明。它基本上说的是 #if 必须有一个匹配的 #endif。编译器不会在包含堆栈上查找匹配的 #if 似乎更像是一个实现细节。

无论如何,预处理器在阶段 4 中以步骤 3 结束对头文件的处理,即

At the end of this phase, all preprocessor directives are removed from the source.

因此当控件返回到源文件的预处理时,它实际包含的文件不包含任何预处理指令。基本上,所有包含的都是一个空文件。这会导致第二个错误,即 #if 没有 #endif,因为确实没有。

关于c++ - 交叉文件 #if 和 #endif - 它应该合法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40034373/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com