Рассмотрим следующие три выражения:
++x;
x += 1;
x = x + 1;
Насколько мне известно, они идентичны в семантике, игнорируя перегрузку операторов на С++. Однако сегодня я прочитал утверждение, что они разные, особенно когда x
объявлено volatile
.
Чтобы проверить это утверждение, я написал следующее и скомпилировал его для PowerPC, AMD64, ARMv6 и 68k:
#include <stdint.h>
static volatile uint64_t x = 0;
void a(void)
{
++x;
}
void b(void)
{
x += 1;
}
void c(void)
{
x = x + 1;
}
На всех четырех этих платформах три функции генерируют идентичный выход ассемблера, независимо от того, находятся ли они на -O1 или -O3. На AMD64 это было всего две инструкции:
incq _x(%rip)
retq
Следовательно, есть ли какая-то правда за этим утверждением? Если да, в чем разница, и как я могу его выставить?
NB: Я прекрасно понимаю, что volatile
не гарантирует атомарность. Это не то, о чем я прошу здесь, - если сама атомарность не отличается от трех.