代码:
#define OPPOSITE(c) (*((typeof(x) *)&(x)))
int foo(volatile int x)
{
OPPOSITE(x) = OPPOSITE(x) + OPPOSITE(x);
return x;
}
int bar(volatile int x)
{
OPPOSITE(x) = OPPOSITE(x) + OPPOSITE(x);
return x;
}
Run Code Online (Sandbox Code Playgroud)
结果(-Os):
foo:
mov DWORD PTR [rsp-4], edi
mov eax, DWORD PTR [rsp-4]
mov edx, DWORD PTR [rsp-4]
add eax, edx
mov DWORD PTR [rsp-4], eax
mov eax, DWORD PTR [rsp-4]
ret
bar:
mov DWORD PTR [rsp-4], edi
mov eax, DWORD PTR [rsp-4]
add eax, eax
ret
Run Code Online (Sandbox Code Playgroud)
或ARM gcc。( -O3 …
维基百科说:
在计算机科学中,如果一个操作、函数或表达式在其本地环境之外修改了某些状态变量值,则该操作、函数或表达式被认为具有副作用,也就是说,除了返回一个值(主要效果)之外,还具有可观察到的效果。操作的调用者。
但是我们如何访问本地环境之外的变量,任何人都可以解释这种情况,副作用,主要效果和序列点吗?
是否有可能通过内存屏障实现易失性变量的相同“保证”(始终读/写内存而不是寄存器)?只需在一个线程中写入变量,然后在另一个线程中读取其值。下面的内容是等价的吗?
#define rmb() __sync_synchronize()
#define wmb() __sync_synchronize()
static volatile int a;
static int b;
//invoked by thread 1
static void writer(void)
{
...
a = 1;
...
b = 1;
wmb();
}
//invoked by thread 2
static void reader(void)
{
...
while (a != 1)
;
// do something
...
while (b != 1)
rmb();
// do something
}
Run Code Online (Sandbox Code Playgroud)
编辑:好的,我知道 volatile 不能保证原子性、可见性或顺序。内存屏障除了排序之外还提供其他功能吗?还有能见度?除了 _Atomic C11 或 gcc/clang 原子内置函数之外,还有其他东西可以保证可见性吗?