【发布时间】:2025-12-22 04:35:11
【问题描述】:
我有一个奇怪的情况,它只出现在 gcc -O0 -g 输出上,不在 gcc -O3 上,不在 MSVC 上,不在 MSVC 调试输出上。
void func(void) {
static int enabled;
if (!enabled) {
// do stuff
enabled = 1;
}
}
仅在 gcc -O0 -g 上出现的问题是,有时 enabled 会返回 0。但并非总是如此,仅在程序执行中的一些罕见点。该函数通常循环通过它。什么会让它对此感到困惑?可以从外部更改“启用”吗?但它是在里面声明的。
编辑:有一种方法可以在函数内部将其设置为 0,但前面有一个根本不打印的大胖 printf [并且在测试中根本没有逻辑方式让它发生条件]。它似乎根本不涉及任何明确启用 = 0 的内容。
EDIT2:它只被主线程调用。
EDIT3:它变得更加奇怪。它不会出现在 linux gcc -O0 -g 上,而只会出现在 mingw-w64 [gcc -O0 -g] 上。
EDIT4:一个 rwatch 和 watch on enabled 似乎表明它在 if (!enabled) 的某些情况下被改变(这应该是只读的)。
EDIT5:在 oftc 的#mingw-w64 的帮助下,如果“布尔序列”被反转,它会出现“修复”,例如enabled 初始化为 1,然后设置为 0。“通过用非零值初始化静态变量,将其放入 .data 部分”“所以关于 lcomm 存在问题”“我假设您在代码中的其他地方”
【问题讨论】:
-
记录这个函数是否可以被多个线程调用。
-
不,只有主线程调用。
-
该变量的初始化程序在哪里?因为现在它没有被初始化为任何东西——我假设你希望它最初是 0?另外你是如何确定它回到 0 的?
-
它是静态的。它被初始化为 0。它回到 0,因为在“做事”中 printf 报告了它,并且我明确地 printf'ed 它的值。
-
您是否尝试过使用 gdb 并在该变量上设置写入观察点?