【问题标题】:Different results using MS Visual Studio vs GCC [duplicate]使用 MS Visual Studio 与 GCC 的不同结果 [重复]
【发布时间】:2012-02-17 23:56:10
【问题描述】:

我编写了一个 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 值。所以我想知道不同的编译器是否会以不同的方式执行宏的过程?

【问题讨论】:

  • 给我们看一些代码。您可能有某种未定义的行为,例如x = x++ + ++x;
  • 结果有何不同?如果一个说“3.14159266666666”而另一个说“3.14159266666667”,你应该阅读"what every computer scientist should know about floating point"
  • 试图直接回答你的问题:他们尽量不这样做。
  • 您也可能对 32 位和 64 位平台之间的差异有疑问。实际上,您应该向我们展示代码(或至少是发生差异的函数)。

标签: c visual-studio-2008 gcc


【解决方案1】:
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

【讨论】:

  • 非常感谢您的详尽回答。
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 2014-11-30
  • 2021-12-23
相关资源
最近更新 更多