infern0 Это стандарт. Точно также для || и &&. Если какой-то компилер не соответствует - это его проблема. (Точнее того, кто на нем пишет
вот, блин... ну что я могу сказать? lisp рулит. Да будет, но не стандартами а компилятором. а нет наврал слегка -- в C++ действительно определён в отличие от C. Каюсь.
rgo А что плохого в том, что компилятору предоставлена свобода оптимизации при вычислении аргументов ? А форсировать порядок вычисления не проблема: давать ф-ции уже вычисленные аргументы во временных переменных.
компилятор пускай оптимизирует, и переменную мне не сложно завести если надо, но с моим пониманием языка это не совпадает... что потенциально ведёт к ошибкам. Хотя я пока не замечал таких ошибок.
rgo Аналогично. Вот что собрал на примере ++i + ++i + i++ + i++ (без оптимизации) : 1. gcc - ошибка (определен?) ; 2. intel - оценивает выражение слева -направо (определен) ; 3. vc - получаем "стандартный глюк"(неопределен); 4. bc - аналогично(неопределен-вообщее говоря оценивает выражение справа - налево). Интересеный получается результат.
Методом тыка баги компиляторов изучать - занятие опасное, лучше стандарт читайте - последний черновик доступен бесплатно.
green С одной стороны это плохо, потому как возникает неоднозначность. Но с другой стороны, нехер писать такие проги, в которых порядок вычисления аргументов определяет результат работы.
_DEN_ Во-во. Возможность оптимизации кода как раз обеспечивается такими "неоднозначностями". Можно конечно ограничить компилятор вплоть до того, что указывать в каком регистре какую переменную держать. И превратить С++ в нечто вроде HLA.
а дело-то в том, что в моей проге порядок вычисления аргументов на результат работы не влияет Компилер просто пытается вычислить аргументы одновременно, не обращая внимание на то, что они используют одну переменную. Мой случай в релизе компилиться вообще во что-то вроде ... push ecx ; arg1 push ecx ; arg2 ... call printf
scf А стандарт разве это запрещает ? - вот всё чем ограничен компилятор согласно стандарту. Т.е. ошибка не в компиляторе, а в компилируемом коде. P.S. Было бы конечно неплохо, если бы компилятор вычислял логические ошибки в программе. Впрочем VC++ некоторые такие ошибки находит (например бесконечную рекурсию).
чем же это он неверен? конкретно этот код верен, тк последовательные вызовы rand независимы между собой (или это не rand). но вот код my_func (peek (stk), push (1, stk)); неверен. Потому, как стандарт не определяет в какой последовательности будут вызываться функции peek и push => компилятор считает что они независимы хотя это не так.
Код (Text): //rand.c - single-threaded version int __cdecl rand (void) { return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff); } Ещё как зависимы!
ты не так понял. Это суть rand -- генерить числа так, чтобы если я переставлю попарно a[2k] и a[2k+1] элементы последовательности, то основные её свойства (из-за которых её назвали rand), не изменяться. Хотя результат вычисления, конечно же будет другим. Кстати, почитал тут стандарт на досуге (С '99 года): результат выражения ++i + ++i + i++ + i++ определён: (i+1) + (i+2) + (i+2) + (i+3). ну и последующее увеличение значения i на 4. То есть если на входе i == 8, то и на выходе -- тоже. Кстати gcc именно это и делает. Не знаю почему у vito gcc отказался компилировать... Либо версия gcc старая (у мя 3.3.6), либо ты пробелы не везде поставил (i+++i согласно стандарту должно разбиваться на токены так: `i' `++' `+' `i', но не `i' `+' `++' `i'), либо я даже не знаю.