0

Любая причина для следующей аберрации?Отклонение Microsoft C от стандарта

Рассмотрим следующую программу C (названный PstFixInc.c)

#include <stdio.h> 
int main (int argc, char *argv []) 
{ 
    int num = 0; 
    num = (num++) % 4; 
    printf ("num: %d\n",num); 
    return 0; 
} 

Если скомпилирован с gcc 4.8.1:

НКУ -o PstFix.exe PstFixInc.c

, а затем вы получаете результат:

Num: 0

Если скомпилирован с Microsoft (R) C/C++ оптимизирующий компилятор версии 18.00.21005.1 для x86

кл PstFixInc.c

и затем казнены, вы получить результат:

Num: 1

+0

его зависит от компилятора! – Sathish

+4

'num = (num ++)% 4;' имеет неопределенное поведение. См. Http://stackoverflow.com/a/4176333/12711 –

+2

Это задается довольно часто - найдите «точки последовательности» для получения дополнительной информации. В принципе, нет, оба компилятора правы, и да, ваш код сломан. – milleniumbug

ответ

4

У вас есть неопределенное поведение, вы изменяете num и используете его предыдущее значение, кроме определения значения, которое должно храниться в одной и той же точке последовательности. Это описано в проекте стандарта C99 секции пункта 2 6.5, который говорит:

между предыдущей и следующей точкой последовательности объект должен быть его сохраненное значение модифицированного не более одного раза по оценке с expression.72) Кроме того, , предшествующее значение должно быть только для чтения, чтобы определить, значение, которое будет stored.73)

Есть также два примера неопределенного поведения:

i = ++i + 1; 
a[i++] = i; 

Первый очень похож на ваш пример. Использование clang даже дает хорошее предупреждение:

warning: multiple unsequenced modifications to 'num' [-Wunsequenced] 
    num = (num++) % 4; 
    ~ ^
+0

Кажется, что улучшенная диагностика, непосредственно ссылающаяся на исходный код, является одним из основных преимуществ clang (против GCC). – tavmem

4

Это неопределенное поведение.

Вы назначаете одну и ту же переменную дважды без чередования sequence point.

0

Эта линия:

num = (num++) % 4; 

не определено поведение по стандарту C. Любой результат, который производит код, является «правильным».