-1

Recently I encountered the following issue. My implementation was looking like this:

#define MY_CODE_VERSION PROJ_VERSION
#include "project.h"
if (3 != MY_CODE_VERSION)

PROJ_VERSION was defined in project.h. Why didn't I get a compilaton warning/error? Because I was trying to define something on a macro that was not known by the time the compiler was reaching the line #define MY_CODE_VERSION PROJ_VERSION.
I took a look over these phases from ANSI C but I can't figure it out the reason (the actual behaviour of the compiler, at which phase MY_CODE_VERSION takes the value of PROJ_VERSION).

My assuption is that this replacement takes place only at line "#if (3 != MY_CODE_VERSION)" and by this time PROJ_VERSION is already known by the compiler from the inclusion of project.h above.

Thank you in advance

4

1 回答 1

2

我不会散布你已经知道的东西。你显然知道的:

6.10.3.4 重新扫描和进一步更换

  1. 在替换列表中的所有参数都被替换并且 # 和 ## 处理已经发生之后,所有的 placemarker 预处理标记都将被删除。然后,重新扫描生成的预处理标记序列以及源文件的所有后续预处理标记,以替换更多宏名称。
  2. 如果在替换列表的扫描过程中找到被替换的宏的名称(不包括源文件的其余预处理标记),则不会替换它。此外,如果任何嵌套替换遇到被替换的宏的名称,它不会被替换。这些未替换的宏名称预处理标记不再可用于进一步替换,即使它们稍后在该宏名称预处理标记将被替换的上下文中进行(重新)检查。
  3. 生成的完全被宏替换的预处理标记序列即使与预处理指令相似,也不会作为预处理指令处理,但其中的所有 pragma 一元运算符表达式随后将按照下面 6.10.9 中的规定进行处理。

简而言之,一旦扩展了宏并且执行了所有字符串化器和连接,则再次扫描生成的“事物”以寻找更多要替换的东西。如果找到相同的名称,则不会替换它。

所以你看到的是标准定义的。

于 2018-08-08T06:00:36.210 回答