使用 MS Visual Studio 与 GCC 的不同结果

发布于 2024-12-28 15:15:38 字数 967 浏览 1 评论 0原文

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

I've written a C program and then compiled and run it in MS Visual Studio and then using GCC. The program makes a few simple math calculations. But the outputs/results I get from both are different. The program is based on macros.

Do these programming environments have a different way of handling macros? If so, what is the difference?

EDIT: Sorry, here's the code.

#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);
}

Here's the output using VS:

f = 7       g = 8 
x = 1     y = 1 
i = 10    j = 11 
x = 1   y = 1

And using GCC:

f = 7   g = 8 
x = 1   y = 1 
i = 10 j = 11 
x = 1  y = -39

The difference is the last y value. So I'm wondering if the different compilers go through the macro's process differently?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

扭转时空 2025-01-04 15:15:38
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
y = mac(++i, ++j);

expands to

y = (++i * ++i) + (++j * ++j) - (2 * ++i * ++j)

Is this really what you had in mind? I imagine you wanted to evaluate the square of (a - b), so you should use:

++i; 
++y;
y = mac(i,j)

Your problem is that the order of evaluation is compiler-dependant. You should never call macros with parameters that have side-effects (like ++) as they may (as in your case) evaluate multiple times. Also your macro should really be written with more brackets, at a minimum like this:

#define mac(a,b) (a)*(a) + (b)*(b) - 2*(a)*(b)

which protects you against calls like

y = mac(i+1, j+1);

which in your example would expand to

y = i+1*i+1 + j+1*j+1 - 2*i+1*j+1

and hence would not evaluate correctly.

Try using the -E option to gcc to check the pre-processor output for macros if in doubt (ie after headers and macros have been expanded but before compilation). It will generate a huge amount of text, but you will be able to find your macro expansion towards the bottom. For example:

gcc -E file.c -o file.txt
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文