ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
19 июля
14939 Топик полностью
ReAl (27.09.2004 12:59, просмотров: 1) ответил Bill на Хм... Насколько я знаю, подобные выражения ВСЕГДА вычисляются СПРАВА НАЛЕВО.
ВЫЧИСЛЯЮТСЯ они так. Но результаты вычислений ПРИСВАИВАЮТСЯ по стандарту в любом месте между sequ points и в любом порядке. Т.е. в примере с обменом двух значений в a может быть записано сначала то, что было вычислено позже (самый левый ^=), потом то, что вычислено раньше (самый правый ^=). Речь тут идёт о порядке выполнения побочных эффектов (присваивающих) выражений, а не о порядке их вычисления. 6.5.16 Assignment operators 3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. The type of an assignment expression is the type of the left operand unless the left operand has qualified type, in which case it is the unqualified version of the type of the left operand. The side effect of updating the stored value of the left operand shall occur between the previous and the next sequence point. Да, я не видел компилятора, который бы скомпилировал тот вариант обмена значений иначе, чем "нам кажется правильным". Но стандарт C99 не гарантирует, что они будут присвоены в таком порядке.
unsigned char a, b;
void foo(void) {
  a ^= b ^= a ^= b;
}

avr-gcc.exe --version
avr-gcc.exe (GCC) 3.4.1

avr-gcc.exe -O2 -Wall  -S foo.c
foo.c: In function `foo':
foo.c:3: warning: operation on `a' may be undefined
Компилирует-то он "правильно", но предупреждает. Так что спокойнее писать a ^= b; b ^= a; a ^= b;