【问题标题】:understanding a C Preprocessor Macro's output vs a line code了解 C 预处理器宏的输出与行代码
【发布时间】:2021-01-26 18:40:20
【问题描述】:
#define AD(x,y) (x+y)
int main()
{
    int x1=5,y1=2,z1;
    int x2=5,y2=2,z2;
    z1 = AD(x1,++y1);
    z2 = (x2+++y2) ;
    printf("%d %d %d\n",x1,y1,z1);
    printf("%d %d %d\n",x2,y2,z2);
}

为什么输出不同? 第一种情况是:5 3 8 第二个是:6 2 7

【问题讨论】:

  • 是的,你需要修复损坏的代码,然后看看你在哪里。
  • 另外注意,不要写这样的代码:z2=x2+++y2; 太难读了,如果使用太多 + 符号,容易出现未定义的行为。
  • @RobertHarvey 完成
  • @RobertHarvey 我认为未定义的行为不适用于这种情况
  • 它没有。你仍然不应该这样写代码。

标签: c macros c-preprocessor


【解决方案1】:

这个表达式

z2=x2+++y2;

由编译器解析,如

z2 = x2++ + y2;

来自 C 标准(6.4 词法元素)

4 如果输入流已被解析为预处理标记 给定字符,下一个预处理标记是最长的 可以构成预处理标记的字符序列。

所以这些标记+++ 被解析为+++。 带有宏的表达式

z1=AD(x1,++y1);

由编译器解析,如

z1 = x1 + ++y1;

由于标记之间的逗号,编译器已经形成了这些标记集x1++y1

所以这两种说法是不同的。

【讨论】:

  • 这是真的吗?预处理器应该进行纹理替换,编译后的代码不应该相同吗?没有空格或括号。
  • 但是如果宏只是我们常说的“文本替换”,那为什么会影响它的解析方式呢? AD(x1, ++y1) 不会在编译阶段简单地导致 (x1+++y1) 吗?
  • @FredLarson 我在不同的编译器中看到了关于在输出标记之间添加空格的不同结果,我认为甚至有一个关于它的问题.. 但我怀疑我现在会找到它
  • @FredLarson:扩展中的+ 是与替换列表中的xy 不同的标记,因此当xy 时它将保持不同的标记已展开。
  • @fred:预处理器不是“文本替换”。它是 token 替换。文本在预处理阶段之前已经被标记化,从预处理器中出现的是经过修改的标记流。除了字符串化和标记连接运算符(###)的操作之外,输出中的每个标记都对应一个输入标记。事实上,一些被描述为预处理器的程序会产生文本输出,重要的是不要被它误导。在内部,编译器正在处理令牌流。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
相关资源
最近更新 更多