2013-08-04 3 views
-2

Просьба объяснить выход для следующего кода:Можете ли вы объяснить вывод для следующего?

#include<stdio.h> 
#include<stdlib.h> 

#define SQUARE(x) (x*x*x) 

int main() { 
    int x = 3; 
    int y = SQUARE(++x)/x++; // Undefined behavior even though it doesn't look 
         // like it here 
    printf("%d %d",x,y); 
    return 0; 
} 

Выход: 7 25

Пожалуйста, объясните, как значение у приходит быть 25?

+0

Ваша квадратная функция должна быть (x * x), вы определили функцию куба – Memolition

+4

Когда вы имеете неопределенное поведение, любой результат одинаково важен, и в любом случае нет никакого «объяснения» любого из них. Поэтому даже когда/если вы «исправляете» свой макрос 'SQUARE', чтобы он квадратизировал вместо кубирования, ваши результаты по-прежнему будут в основном бессмысленными. –

+1

Вы сказали ** Неопределенное поведение ** в комментарии сами, так что объяснить? –

ответ

0

Макрос ошибочно назван, но это просто красная селедка. Два утверждения расширяться:

int x = 3; 
int y = (++x * ++x * ++x)/x++; 

Это неопределенное поведение, поскольку х модифицируется больше, чем когда-то между точками последовательности. Компилятору разрешено делать что угодно; он может чередовать использование x и до и после приращения x почти так или иначе. Он может делать вещи, слева направо, в этом случае, вы получите:

int y = (4 * 5 * 6)/6; 

Согласно этой схеме, x сейчас 7 и y теперь 20.

Он мог бы сделать все правильно, чтобы -Выберите:

int y = (7 * 6 * 5)/3; 

Теперь y 70.

это могло бы кэшировать значение x в практически любой точке на d использовал его. Попробуйте запустить свою программу под различными компиляторами с различными уровнями оптимизации. gcc -O4 отличается от cc? Фактически, цитируя файл интернет-жаргона:

носовые демоны: n.

Признанная сокращенность группы Usenet comp.std.c для любого непредвиденного поведения компилятора C при обнаружении неопределенной конструкции. Во время обсуждения этой группы в начале 1992 года регулярно отмечалось: «Когда компилятор встречает [данную неопределенную конструкцию], это законно для него, чтобы заставить демонов вылететь из вашего носа» (подразумевается, что компилятор может выбрать любой произвольно странный способ интерпретировать код без нарушения стандарта ANSI C). Кто-то другой следил за ссылкой на «носовых демонов», которые быстро установились. Исходный пост доступен в Интернете по адресу http://groups.google.com/groups?hl=en&selm=10195%40ksr.com.

Итак, я был бы намного внимательнее здесь. Вы хотите, чтобы демоны вылетели из вашего носа?

+0

Расширение макроса также добавляет круглые скобки, это 'int y = (++ x * ++ x * ++ x)/x ++;' – user2485710

+0

True. Я отредактирую. –

Смежные вопросы