int func(int& a)
{
int b = a;
int c = a;
return a + b + c;
}
int main()
{
int a = 1;
return func(a);
}
利用 g++ test.cpp -g -O2 -o test.out && objdump -S test.out
Disassembly of section .text:
00000000000004f0 <main>:
int main()
{
int a = 1;
return func(a);
}
4f0: b8 03 00 00 00 mov $0x3,%eax
4f5: c3 retq
4f6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4fd: 00 00 00
从上面看出,func(a) 这个函数调用,直接被优化掉了。
这么优化有什么问题吗?
单线程没问题,但多线程就有问题了,如果是多线程,a的值虽然在当前上下文中不会被修改,但可能正在被其他线程修改啊。于是上面的优化就不对了。(假设我们需要做的是无锁编程,有锁编程自然不会需要用到volatile
关键字)
那么,volatile
关键字在这里就可以帮助我们了,volatile
关键字提醒编译器: a
可能随时被意外修改,意外的意思是虽然当前这段代码里看起来a
不会变,但可能别的地方正在修改a
的值,所谓"别的地方",某些情况下指的就是其他线程了。
下面是加上volatile
关键字后的汇编代码。
int fun(volatile int& a)
{
int b = a;
int c = a;
return a+b+c;
}
int main()
{
volatile int a = 1;
return fun(a);
}
利用 g++ test2.cpp -g -O2 -o test2.out && objdump -S test2.out
Disassembly of section .text:
00000000000004f0 <main>:
return a + b + c;
}
int main()
{
volatile int a = 1;
4f0: c7 44 24 fc 01 00 00 movl $0x1,-0x4(%rsp)
4f7: 00
int b = a;
4f8: 8b 44 24 fc mov -0x4(%rsp),%eax
int c = a;
4fc: 8b 54 24 fc mov -0x4(%rsp),%edx
return a + b + c;
500: 8b 4c 24 fc mov -0x4(%rsp),%ecx
504: 01 c8 add %ecx,%eax
506: 01 d0 add %edx,%eax
return func(a);
}
508: c3 retq
509: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
另外注意:volatile
其实是写给编译器看的东西,CPU无感知,也就是说它没有定义 happens-before 的关系,不能当作传统的原子变量来用。
网友评论