Re: ругающим компилятор
От: jazzer Россия Skype: enerjazzer
Дата: 19.06.14 09:42
Оценка: 57 (5) +1
что он-де предполагает чего не должен.
Т.е. предполагает, что знаковые целые никогда не переполняются.
Так вот, он делает это на основании вашего же обещания. Это вы сами при помощи опции -O2/O3/Os (это просто (почти) комбинации других опций) пообещали ему, что переполнений нет и что он может, исходя из этого обещания, оптимизировать программу как хочет:

-fstrict-overflow

Allow the compiler to assume strict signed overflow rules, depending on the language being compiled.
For C (and C++) this means that overflow when doing arithmetic with signed numbers is undefined, which
means that the compiler may assume that it does not happen. This permits various optimizations.
For
example, the compiler assumes that an expression like "i + 10 > i" is always true for signed "i". This
assumption is only valid if signed overflow is undefined, as the expression is false if "i + 10"
overflows when using twos complement arithmetic. When this option is in effect any attempt to
determine whether an operation on signed numbers overflows must be written carefully to not actually
involve overflow.

This option also allows the compiler to assume strict pointer semantics: given a pointer to an object,
if adding an offset to that pointer does not produce a pointer to the same object, the addition is
undefined. This permits the compiler to conclude that "p + u > p" is always true for a pointer "p" and
unsigned integer "u". This assumption is only valid because pointer wraparound is undefined, as the
expression is false if "p + u" overflows using twos complement arithmetic.

See also the -fwrapv option. Using -fwrapv means that integer signed overflow is fully defined: it
wraps. When -fwrapv is used, there is no difference between -fstrict-overflow and -fno-strict-overflow
for integers. With -fwrapv certain types of overflow are permitted. For example, if the compiler gets
an overflow when doing arithmetic on constants, the overflowed value can still be used with -fwrapv,
but not otherwise.

The -fstrict-overflow option is enabled at levels -O2, -O3, -Os.


Так что, если вы хотите все оптимизации, кроме этой, надо либо
1) отозвать обещание явно при помощи -fno-strict-overflow (т.е. переполнения возможны); либо
2) определить арифметику для знаковых так же, как и для беззнаковых, чтобы переполнения не происходило (а все вычисления просто шли по модулю 2), при помоши -fwrapv.

Ну и третье решение — использовать беззнаковые типы для переменных, которые не предполагают отрицательных значений.

ЗЫ Правильной практикой является изучение того, какие оптимизации включаются на каждом уровне, и проверка, что ваш код требованиям этих оптимизаций соответствует. Либо неиспользование "сборных" уровней оптимизаций и вместо этого использование ручного списка индивидуальных опций — тогда апгрейд компилятора вам ничего не поломает.

ЗЗЫ Беда только в том, что "сборные" опции — это не только индивидуальные опции, там есть еще некий темный набор действий, опциями не покрытый — я на это напарывался: включаешь -O2, отключаешь все опции, из которых он, вроде бы, состоит — и все равно поведение компилятора отличается.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.