简体   繁体   English

在 C 中使用嵌套宏

[英]Using Nested macros in C

#include "stdafx.h"
#include<stdio.h>

#define PR(x) printf("%d\t",(int)(x));
#define PRINT(a,b,c) PR(a) PR(b) PR(c)
#define MAX(a,b) (a<b?b:a)

int main()
{
    int x=1,y=2;
    //PR(MAX(x++,y));
    PRINT(MAX(x++,y),x,y);  //2,2,2
    PRINT(MAX(x++,y),x,y);  //2,3,2
    return 0;
}

x is 1 so the 3 values to be passed as arguments in PRINT is 2 2 2. x为 1,因此在 PRINT 中作为 arguments 传递的 3 个值是 2 2 2。

Then in the second PRINT the values that will be passed is 2 3 2. So the output should be 2 2 2 2 3 2. But this program outputs as 2 2 2 3 4 2.然后在第二个 PRINT 中,将传递的值是 2 3 2。所以 output 应该是 2 2 2 2 3 2。但是这个程序输出为 2 2 2 3 4 2。

Your MAX macro is bad.你的MAX宏不好。 It evaluates one of its arguments twice.它评估其 arguments 之一两次。

 MAX(x++,y)

expands to:扩展为:

 (x++ < y ? y : x++)
                ^^^

So x is incremented twice if it started out smaller than y .因此,如果 x 开始时小于y ,则x会增加两次。

There is no undefined behavior in that code because there is a sequence point between the evaluation of the first part of the ternary operator and the part that is selected.该代码中没有未定义的行为,因为在三元运算符的第一部分的评估和被选择的部分之间存在一个序列点 The whole PRINT expression expands to:整个PRINT表达式扩展为:

 printf("%d\t", (x++ < y ? y : x++));
 printf("%d\t", (x));
 printf("%d\t", (y));

Which is all fine.这一切都很好。 This does not mean you should be using such macros.并不意味着您应该使用此类宏。 Use simple functions, and let the compiler do its job of type-checking and inlining what it thinks is best.使用简单的函数,让编译器完成类型检查和内联它认为最好的工作。

Your macros have several problems:您的宏有几个问题:

  • Never hide a ;永远不要隐藏; inside a macro but have it behave like an ordinary statement在宏内部,但让它表现得像一个普通的语句
  • Don't write macros that evaluate their arguments multiple times不要编写多次评估其 arguments 的宏
  • always put parentheses around macro parameters such that you know the precedence of all operators.始终在宏参数周围加上括号,以便您知道所有运算符的优先级。

Your MAX(x++,y) call translates to (x++<y?y:x++) and results in double modification of x during the first call.您的MAX(x++,y)调用转换为(x++<y?y:x++)并导致在第一次调用期间对x进行双重修改。

PRINT((MAX(x++,y),x,y) -> PR(MAX(x++,y)) PR(x) PR(y) -> PR(x++ PRINT((MAX(x++,y),x,y) -> PR(MAX(x++,y)) PR(x) PR(y) -> PR(x++

x = 1, y = 2 Does PR(2 since 1<2) and increments x to 2 Then PR(2) PR(2) - Hence output 2 2 2 x = 1, y = 2 执行 PR(2 因为 1<2) 并将 x 增加到 2 然后 PR(2) PR(2) - 因此 output 2 2 2

Next PR(MAX(x++ (ie2) < 2 - false)? 2: x++ (ie use incremented value of x from condition (3) then output 3 and increment x to 4) - hence x gets incremented twice下一个 PR(MAX(x++ (ie2) < 2 - false)? 2: x++ (即使用条件 (3) 中 x 的增量值,然后 output 3 并将 x 增量为 4) - 因此 x 增加了两次

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM