MSVC 8.0 Код (Text): int plus(int a, int b) { return a + b; } int main() { int x = 0; x = plus(++x, ++x); std::cout << x; return 0; } На экране "4". Должно быть "3". Сначала, корда я их просто оператором складывал, я подумал что для операторов, работающих со встроенными типами, могут быть оговорки в стандарте. Но когда то же самое оказалось для функции, то это уже бред. У кого что такая штука напечатает?
_DEN_ Порядок вычисления аргументов ф-ций (а также большинства операторов) не определён. Так что компилятор волен выбирать наиболее оптимальный способ, исходя из предположения о независимости результата от порядка вычисления. Теоретически, он может для вычисления каждого аргумента запускать отдельный поток.
Я уже про такое слышал. Вроде где-то в стандарте оговаривается, что поведение компилятора не предсказуемое при использовании ин(де)крементирующих операциях в параметрах функции, то бишь это на усмотрение разработчиков компиляторов. В принципе результат правельный, если учитывать что значение аргументов вычисляется до помещения их в стек.
>> Должно быть "3" почему? машинный код в любом случае будет сгенерён таким образом, что операции инкремента выполнятся до того, как управление получит ф-ция plus
_DEN_ 5.2.2 : The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
n0name ГЫ ))) Почему 14, я так и не понял ( Первое ++и дает 6 Второе ++и дает 7 ну и 6 + 7 дает 13 Почему 14 ? Глянул в дизасм: Код (Text): 7: i = ++i + ++i; 0040155F mov eax,dword ptr [ebp-4] 00401562 add eax,1 00401565 mov dword ptr [ebp-4],eax 00401568 mov ecx,dword ptr [ebp-4] 0040156B add ecx,1 0040156E mov dword ptr [ebp-4],ecx 00401571 mov edx,dword ptr [ebp-4] 00401574 add edx,dword ptr [ebp-4] 00401577 mov dword ptr [ebp-4],edx почему такое? Этож неправильно! Почему он должен был складывать eax, ecx. Получается что ecx + ecx! MS VC++ 6.0
_DEN_ В Стандарте даже специальный пример дан: Код (Text): i = ++i + 1; // the behavior is unspecified
Ну е-мое... При чем тут порядок вычисления аргументов? Во-первых, я знаю что он не определен. Во-вторых, в моем примере он совершенно не влияет на результат и к сути вопроса вообще никакого отношения не имеет. Вопрос в том, как происходит само вычисление. На сколько я пониаю, никакой оператор не можен быть выполнен до того, как до него не дошло управление. plus(++i, ++i); Для того чтобы вызвать функцию, надо вычислить ее аргументы. Аргументы вычисляются последовательно. Т.к. в моем примере последовательность на результат не влияет, то будем считать, что они вычисляются по порядку. Сначала первый. plus(++i, ...); ++i дает 1. Все. Первый параметр функции вычеслен. Он равен 1 и больше меняться не будет. Готово. Идем дальше. Второй параметр. plus(..., ++i); i уже равно 1, поэтому ++i равно 2. Второй параметр вычеслен. Он равен 2 и меняться тоже не будет. Все, аргумены готовы, известны их значения, можно вызывать функцию. plus(1, 2); То, что студия считает что резутьтатом будет 4, говорит о том, что она думает, что ++i должно выполниться еще ДО того, как началось вычисление аргументов функции. На сколько я понимаю, это НЕПРАВИЛЬНО, т.к. любой оператор начинает свою работу не раньше того момента, как до него дошло управление. RedLord Согласен с Comeau. maxdiver Ты уверен что там префиксный, а не постфиксный?
_DEN_ Стандарт не обязывает компилятор вычислять аргументы последовательно. Он может вычислять их даже одновременно. Процесс вычисления аргумента состоит из а. инкремента x б. передачи х в ф-цию (записи х в стек). В твоём случае компилятор VC8, вероятно, вычисляет так (1 - первый арг., 2 - второй арг.): 1а, 2а, 1б, 2б. В результате вызывается plus(2, 2). А Comeau так: 1а, 1б, 2а, 2б Результат: plus(1, 2). В данном случае это показывает, что компилятор VC8 использует больше возможностей для оптимизации, чем Comeau. --- Стандарт лишь регламентирует, что аргументы должны быть вычислены до выполнения кода ф-ции.
_DEN_ Уверен. Потому что я сделал копи-паст Впрочем, green уже всё объяснил. И префиксный, и постфиксный операторы могут дать побочные эффекты.
Mental_Mirror К сожалению закачать никуда не могу - размер 2.4 Мб, и связь обрывается. Погугли - ключевые слова: " C++ International Standard 14882:2003 " (у меня такой версии).
maxdiver Я не понимаю почему это UB. green Откуда уверенность в том, что вычисление конкретного аргумента не обязано быть атомарным?