27.01.2007, 15:34
общий
это ответ
Здравствуйте, Platon!
Никогда не используйте подобных выражений. ANSI C++ не дает никаких гарантий на то или иное поведение подобного кода. Используйте оператор инкремента/декремента не более одного раза в одном операторе. Сам господин Страуструп пишет о том, что таких случаев нужно избегать.
Другой пример: array[++i] = ++i;
Однако, отвечу на ваш вопрос конкретно.
Функция printf объявлена как __cdecl, что, кроме прочих нюансов, горовит компилятору, что параметры передаются в функцию через стек, причем добавляются в него справа налево. Предполагаемые действия компилятора: инкрементируем n, добавляем n в стек, инкрементируем n, добавляем n в стек, инкрементируем n, добавляем n в стек, добавляем в стек адрес строки формата. Функция printf анализирует строку формата и, при нахождении ссылки на подстановку целого числа, берет из стека ближайшие от адреса строки формата 4 байта. Т.о. там будет расположено число n, которое было добавлено в стек последним, имеющее значение 4. Дальше последуют 3 и 2.
Но возможно и другое поведение компилятора. Например, сначала n трижды инкрементируется, а потом трижды передается в функцию. Тогда результат, очевидно, будет 4 4 4. Мало ли других вариантов, поэтому на разных компиляторах результат может быть разным.
Возможно, поведение было бы другим, если бы функция была не __cdecl, а, например, __fastcall (передача параметров через регистры).
PS Ценю ваше стремление к познанию тонких мест в программировании.