编译器颠倒了 C 行顺序?

C line order reversed by compiler?

我有这个示例代码:

#include <stdio.h>
#include <stdlib.h>

int addOne();

int main(int argc, char** argv) {
    char s[100];
    int x = 1;
    x = addOne(x);
    printf("%d",x);
    gets(s);
    return (EXIT_SUCCESS);
}

int addOne(int j) {
    return j + 1;
}

您可以看到 printf 在 gets(s) 之前,但是当我 运行 代码时,它先询问字符串,然后再打印数字。我将 NetBeans 与 Cygwin gcc 编译器一起使用。有什么我想念的吗?是编译器错误吗?

printf() 通常是行缓冲的。所以 printf 的输出不会出现在屏幕上,直到缓冲区被刷新。

\n 添加到 printf,它应该会按预期工作。

printf("%d\n",x);

如果不需要,您可以使用setbuf(stdout, NULL);禁用缓冲。

顺便说一下,你永远不应该 gets()。请改用 fgets()。因为gets()是容易出现缓冲区溢出的漏洞,从C99开始就被废弃了,在C11中已经完全移除。


关于您怀疑编译器正在对行重新排序:编译器确实可以重新排序指令并且被允许合法地这样做。 但前提是不影响程序的可观察效果

考虑以下代码,

void func(void)
{
   int a = 2;
   int b = 3;

   a = a * 2;  //line 1
   b = b + 3;  //line 2

   printf("%d\n", a+b);
}

编译器可以按任何顺序(第 1 行或第 2 行)计算 ab,因为它不会影响代码的行为。或者它甚至可以简单地将函数替换为:

void func(void)
{
   printf("%d\n", 10);
}

通常情况下,编译器会出于优化目的进行此类转换,并且是允许的。在您的代码中,编译器无法执行此类代码转换,因为它会影响代码的可观察行为。