【发布时间】:2021-10-15 16:46:50
【问题描述】:
我有一个简单的 sn-p,其中编译器优化了变量“done”
#include <pthread.h>
#include <stdbool.h>
bool done = false;
void *func(void *args)
{
done = true;
return NULL;
}
main()
{
pthread_t p1;
pthread_create(&p1, NULL, func, NULL);
printf("waiting\n");
while(!done)
{}
printf("moving on...\n");
}
这里,在没有 volatile 关键字的情况下,变量“done”被优化掉并进入无限循环。
我正在编译使用:
gcc -O2 volatile.c -lpthread
但是当我使用简单的 func() 版本时:
#include <stdbool.h>
bool done = false;
void func()
{
done = true;
}
main()
{
func();
printf("waiting\n");
while(!done)
{}
printf("moving on...\n");
}
但是这里的变量“done”没有优化出来,两者有什么区别?
编译器在第二种情况下猜到“完成”会改变一些方式,但在 Pthread 的情况下不会?
我的 GCC 版本是:
gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
【问题讨论】:
-
“优化”是什么意思?您没有提供您使用的任何命令行选项。
-
variable "done" is optimized away你怎么知道它被“优化掉了”?只是true。我是bool done = true;,你是说bool done = false;吗? -
@KamilCuk,是的,我刚刚更新了 sn-p。
-
那么,现在,这不是一个无限循环..
-
顺便说一下,对于可移植的 C,
volatile不足以防止数据竞争和未定义的行为。您必须将done设为atomic类型(这也将防止不必要的优化)