【发布时间】:2020-12-12 18:48:31
【问题描述】:
我正在尝试制作一个打印“eggy weggy”的程序。通过将字符的值存储在 3 个变量(x、y 和 z)中。我已经尝试添加一个for 循环来打印几次,但这就是奇怪的开始。如果我将printf("%p\n%p\n%p\n%p\n", &x, &y, &z, &i); 放在代码中的任何位置,则输出符合要求。但是如果我排除这个,程序只会打印多次“eggy”。
#include <stdio.h>
int main(int argc, char* argv[])
{
unsigned x = 2036819813; //sequence of 'y', 'g', 'g', 'e'
unsigned y = 1734702880; //sequence of 'g', 'e', 'w', ' '
unsigned z = 3045735; //sequence of '\0', '.', 'y', 'g'
char* ptr = (char*)&x;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%s\n", ptr);
}
printf("%p\n%p\n%p\n%p\n", &x, &y, &z, &i);
return 0;
}
输出:
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
eggy weggy.
0x7ffc2844d000
0x7ffc2844d004
0x7ffc2844d008
0x7ffc2844d00c
现在没有printf("%p\n%p\n%p\n%p\n", &x, &y, &z, &i);
输出:
eggy
eggy
eggy
eggy
eggy
eggy
eggy
eggy
eggy
eggy
另外,如果我不循环执行此操作,它会打印出“eggy weggy”。正确。这对我来说似乎很奇怪。我不知道变量的状态可以通过是否观察到它们的值来确定。这是一个错误吗?这是一个优化的东西吗?任何信息表示赞赏:)
注意:我正在使用 gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 和参数 -O0 -std=c89 -Wall(我没有在量子计算机上运行它)
编辑:当我在 clang 中编译代码时,代码会按预期运行,但我不得不切换 x 和 z 的声明顺序,因为 clang 将较新的变量放在较低的内存地址中旧变量,不像 gcc 将它们放在更高的地址。
【问题讨论】:
-
由于没有
printf的代码没有明确使用y和z,并且代码无论如何都依赖于未定义的行为,那么可能y和z已经被优化了。 -
“我不知道变量的状态可以通过是否观察到它们的值来确定。”当您在量子计算机中运行程序时会发生这种情况
-
@WeatherVane 这可能是这种情况,但如果我删除
i和for循环并且不使用printf,它仍然可以正常工作 -
只需编写正确的代码,不要费力去理解为什么不正确的代码可能有效,也可能无效。
-
你试过用
-O0编译吗?