Выходной вопрос в макросах?

У меня есть следующий код C:

#include <stdio.h>

int x = 2;
int f (int z) { int temp = x; x += 2*z; return temp; }

#define MIN(X,Y)  ((X) < (Y) ? (X) : (Y))  /* side effects may cause error */
int MIN_fix(X,Y) { if (X < Y) return X; else return Y; }

int main () {
unsigned char b = 0x3, c = 0x1;
printf("result> %d, %d\n", MIN(b+c, f(3)), MIN_fix(b+c, f(3)));
}

почему я получил "результат> 4, 2", если он был 8 вместо 4?

1 ответ

Решение

Поскольку это не было отклонено или закрыто как дубликат, я постараюсь объяснить

Давайте посмотрим на ваш printf вызов:

printf("result> %d, %d\n", MIN(b+c, f(3)), MIN_fix(b+c, f(3)));

Сейчас b+c эффективно постоянное значение (4), так что это превращается в

printf("result> %d, %d\n", MIN(4, f(3)), MIN_fix(4, f(3)));

Если мы расширим MIN Макро-вызов и удаление ненужных паренов, мы получаем следующее

printf("result> %d, %d\n", 4 < f(3)? 4 : f(3), MIN_fix(4, f(3)));

Таким образом, у нас есть 3 звонка f(3) в этой строке кода. Первые три вызова этой функции возвращают 2, 8 и 14 соответственно. Но нет никакой гарантии, в каком порядке эти звонки будут оценены.

Пусть f1=2, f2=8 и f3=14. Ваш printf может быть любым из следующих с их выводом в комментарии

printf(..., 4<f1?4:f2, MIN_fix(4,f3)); //  8, 4
printf(..., 4<f1?4:f3, MIN_fix(4,f2)); // 14, 4
printf(..., 4<f2?4:f1, MIN_fix(4,f3)); //  4, 4
printf(..., 4<f2?4:f3, MIN_fix(4,f1)); //  4, 2
printf(..., 4<f3?4:f1, MIN_fix(4,f3)); //  4, 4 
printf(..., 4<f3?4:f2, MIN_fix(4,f1)); //  4, 2

Любые из выходных данных действительны - потому что у вас есть неопределенное поведение

Другие вопросы по тегам