Здравствуйте, CreatorCray, Вы писали:
V>>Я прошёлся по куче компиляторов — даже когда is_max не уничтожается (подавал не константу компиляции) — эффект был тот же на -O2, всё те же oops для первоначального варианта. )) CC>Алгоритмические оптимизации делаются во фронтэнде. И если он решил что тут будет всегда false, потому что на абстрактное (x + 1) < x он смотрел без учёта размерностей, то бэкенд именно return false, как ему сказали и сгенерирует.
Не, там же даётся дизассембинг кода. Происходит именно честный вызов is_max (если подавать не константу компиляции), вот его тело на экране, можно почитать ассемблерные инструкции и посмотреть, почему oops.
В режиме O1 и O2 в x64 у многих компиляторов не возникает переполнения, т.к. происходит инкремент 64-битного регистра (оптимизация заключается в замене сложения инкрементом, но нет команды инкремента полурегистра), т.е. результат инкремента всё еще продолжает оставаться положительным, поэтому задуманный первоначальный фокус и не срабатывает.
Именно поэтому вторым решением я предложил смотреть прямо в нужный бит, т.к. логику решений Синклер описал — максимальное неотрицательное число это такое, после прибавления единицы к которому вознрикает переполнение. В нужном бите возникает единичка, конечно, просто этот бит не всегда старший в промежуточных вычислениях. ))