22:29
Как я тупил
...
int a,b;
a=b=0;
b=f(&a)*a;
...
Функция f возвращает некое значение, а второе значение записывает в память по адресу &a.
Итак. Меня вдруг начал мучить сакраментальный вопрос (потому что я начитался книжек типа "почему 2+2=5986?") -- а собственно могу ли я гарантировать, что функция f(...) будет вызвана ДО того, как будет использован правый операнд? Другими словами, не может ли оказаться так, что сначала будет зафиксировано при вычислении выражения a==0, потом вызовется функция, вернёт 1 и в a запишет 1. Тогда произведение должно будет равняться одному. Но a-то уже зафиксировано в регистре и будут умножать на ноль! И получим ноль.
Я стал вспоминать ассоциативность (о господи! она-то тут причём?!) умножения. Не вспомнил. Открыл таблицу приоритетов. Ассоциативность оказалась слева направо. Я подумал -- хорошо, значит будет сначала первый операнд вычислен! А потом заметил колонку "приоритет" и стал её изучать. Тут ко мне снизошло озарение. Господи, у вызова функции приоритет 16, а у умножения гораздо ниже. То есть функция по-любому будет сначала вычислена. А я парился.
Во дурак.
17.01.2012 в 22:42