我编写了一个C程序,然后在MS Visual Studio中编译并运行它,然后使用GCC。该程序进行了一些简单的数学计算。但是我从两者得到的输出/结果是不同的。该程序基于宏。
这些编程环境是否有不同的处理宏的方式?如果是这样,有什么区别?
编辑:对不起,这是代码。
#include <stdio.h>
#define mac(a,b) a*a + b*b - 2*a*b
int func(int a, int b) {
return (a*a + b*b - 2*a*b);
}
main() {
int f, g, i, j, x, y;
printf("Please enter two integers\n");
scanf("%d%d", &f, &g);
printf("f = %d\tg = %d\n", f, g);
i = f;
j = g;
x = func(i, j);
y = mac(i, j);
printf("x = %d\ty = %d\n", x, y);
x = func(++i, ++j);
i = f;
j = g;
y = mac(++i, ++j);
printf("i = %d\tj = %d\n", i, j);
printf("x = %d\ty = %d\n", x, y);
}
这是使用VS的输出:
f = 7 g = 8
x = 1 y = 1
i = 10 j = 11
x = 1 y = 1
使用GCC:
f = 7 g = 8
x = 1 y = 1
i = 10 j = 11
x = 1 y = -39
差异是最后的y值。所以我想知道不同的编译器是否会以不同的方式完成宏的过程?
答案 0 :(得分:5)
y = mac(++i, ++j);
扩展为
y = (++i * ++i) + (++j * ++j) - (2 * ++i * ++j)
这真的是你的想法吗?我想你想要评估(a - b)的平方,所以你应该使用:
++i;
++y;
y = mac(i,j)
您的问题是评估顺序与编译器有关。您永远不应该使用具有副作用的参数(如++)调用宏,因为它们可能(如您的情况)多次评估。另外你的宏应该用更多括号编写,至少这样:
#define mac(a,b) (a)*(a) + (b)*(b) - 2*(a)*(b)
可以保护您免受
之类的调用y = mac(i+1, j+1);
在您的示例中将扩展为
y = i+1*i+1 + j+1*j+1 - 2*i+1*j+1
因此无法正确评估。
如果有疑问,请尝试使用gcc的-E选项来检查宏的预处理器输出(即在扩展标头和宏之后但在编译之前)。它会生成大量的文本,但是你可以找到你的宏扩展到底部。例如:
gcc -E file.c -o file.txt