Достали, право слово...
2007-05-12 07:07ufm@home ~ $ cat t.c
#include <stdio.h>
int main(void) {
int i;
volatile int j;
i = j = 5;
i = ++i + ++i;
j = ++j + ++j;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = i++ + ++i;
j = j++ + ++j;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = i++ + i++;
j = j++ + j++;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = ++i + i++;
j = ++j + j++;
printf ("i == %d j == %d\n",i,j);
return 0;
}
ufm@home ~ $ gcc t.c
ufm@home ~ $ ./a.out
i == 14 j == 13
i == 13 j == 11
i == 12 j == 10
i == 13 j == 12
ufm@home ~ $
#include <stdio.h>
int main(void) {
int i;
volatile int j;
i = j = 5;
i = ++i + ++i;
j = ++j + ++j;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = i++ + ++i;
j = j++ + ++j;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = i++ + i++;
j = j++ + j++;
printf ("i == %d j == %d\n",i,j);
i = j = 5;
i = ++i + i++;
j = ++j + j++;
printf ("i == %d j == %d\n",i,j);
return 0;
}
ufm@home ~ $ gcc t.c
ufm@home ~ $ ./a.out
i == 14 j == 13
i == 13 j == 11
i == 12 j == 10
i == 13 j == 12
ufm@home ~ $
(no subject)
Date: 2007-05-12 12:42 (UTC)Инерементируем i, получается 6, берем это значение, потом еще раз инкрементируем i, получается 7, складываем 6 и 7, получается 13.
На деле, если оно не volatile, то оно сначала два раза инкрементируется, а потом уже результат сам с собой складывается, получается 14.
А почему так - я не понимаю.
(no subject)
Date: 2007-05-12 12:50 (UTC)(no subject)
Date: 2007-05-12 19:40 (UTC)(no subject)
Date: 2007-05-12 20:05 (UTC)Непонятно, почему складывается дважды последнее значение i (7), а не то, которое было на момент после собственно инкремента (в одном случае 7, в другом 6).
А еще непонятнее, почему в случае volatile оно происходит по-другому.
(no subject)
Date: 2007-05-13 06:02 (UTC)(no subject)
Date: 2007-05-13 06:04 (UTC)i == 14 j == 14
i == 13 j == 13
i == 12 j == 12
i == 13 j == 13
Это cl.exe из VC 8 Epxress (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86)
(no subject)
Date: 2007-05-13 07:13 (UTC)Вообще, по моим ощущениям тут должно быть так:
(1) Инкремент. Его результат -- 6. В i по-прежнему 5, так как сайд-эффект промоутится только на Sequence point, но мы помним, что надо записать 6 в i.
(2) Инкремент. Его результат -- 6. В i по-прежнему 5, так как сайд-эффект промоутится только на Sequence point, но мы помним, что надо записать 6 в i.
(3) Складываем 6 и 6, результат -- 12
(4) i = 12
(5) Конфликт срабатывания сайд-эффектов (1) и (2), то самое неопределённое поведение...
Как разрулится конфликт (Вплоть до инкрементирования i опять дважды) -- вопрос компилятора...