Ответ 1
AFAIK gcc не предоставляет такой опции. В стандарте, как вы сказали, говорится:
N3690 - §5.8.3
Значение E1 → E2 - это позиции E1 с правым сдвигом E1. Если E1 имеет unsigned type или если E1 имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью частного E1/2E2. Если E1 имеет подписанный тип и отрицательное значение, результат значение определяется реализацией.
а это означает выполнение
int si = -1;
int right = si >> 1;
может привести или не дать -1 в результате. Определено реализация. И это означает, что компилятор не вынужден выдавать предупреждение, как "другие компиляторы могут сделать это другим способом".
Ниже приводятся некоторые причины этого выбора.
В оригинальном отрывке K & R говорится:
"Правое смещение беззнакового числа заполняет освобожденные биты с 0. Вправо смещение знаковой величины будет заполняться знаковыми битами (арифметический сдвиг) на некоторых машинах, таких как PDP-11, и с 0 бит (логический сдвиг) на других."
это означает, что операция зависит от архитектуры. Причина этого в том, что некоторые архитектуры быстро выполняют одно из двух, но не оба.
Эта причина плюс тот факт, что полезность сдвигов с расширением знака является маргинальной, поэтому стандарт принимает решение о том, чтобы оставить ее "определенной в реализации". Под "полезностью сдвигов с расширением знака" я подразумеваю, что правое смещение отрицательного знакового целого арифметически не работает как положительный аналог (поскольку потеря 1 справа делает отрицательное число меньше, то есть больше по модулю)
+63 >> 1 = +31 (integral part of quotient E1/2E2)
00111111 >> 1 = 00011111
-63 >> 1 = -32
11000001 >> 1 = 11100000
Ссылки для дальнейшего чтения:
fooobar.com/questions/231815/...
http://www.ccsinfo.com/forum/viewtopic.php?t=45711
https://isocpp.org/std/the-standard
Изменить: если приведенное выше не устраняет проблему (т.е. код действителен, почему компилятор предупреждает об этом?) Я предоставляю второе решение: AST matchers
Как описано здесь: http://eli.thegreenplace.net/2014/07/29/ast-matchers-and-clang-refactoring-tools/ вы можете написать код, чтобы быстро идентифицировать все пятна с правильными смещениями с целыми целями в вашей программе.
Подумайте об этом как о "написании моей маленькой одностадийной проверки статического анализа".
Изменить 2: вы также можете попробовать другие инструменты для статического анализа, у clang есть опция - fsanitize = shift, которая может работать на вас. AFAIK также для gcc они внедряли дезинфицирующее средство поведения undefined, которое могло бы помочь диагностировать эти ошибки. Я не следовал этой истории, но я думаю, вы тоже могли бы попробовать.