Краткое объяснение того, что компилятор не выдает предупреждение в таких случаях, заключается в том, что это не требуется.
Определение «undefined» в стандарте также явно указывает, что «диагностика не требуется». Это означает, что стандарт не требует реализации для выдачи диагностики в таких случаях. Причина этого в том, что технически компиляторы могут быть не в состоянии обнаружить все экземпляры неопределенного поведения в разумные сроки или (в некоторых случаях) вообще. Некоторые случаи могут быть обнаружены только во время выполнения. Компиляторы - это сложные фрагменты кода, поэтому - даже если человек может легко распознать проблему, - компилятор может этого не сделать (с другой стороны, компиляторы также обнаруживают проблемы, которые люди не могут легко найти).
Когда диагностика не требуется, есть несколько вещей - все по усмотрению - которые должны произойти, прежде чем компилятор выдаст предупреждение.
Первое, что случается, вызывает беспокойство по поводу «качества реализации» - поставщик или разработчик компилятора решает написать код, который обнаруживает конкретные случаи, и другой код, который выдает предупреждение.
Два шага (обнаружение случая и предупреждение о нем) являются отдельными и полностью дискреционными - стандарт не требует диагностики, поэтому, даже если написан код, обнаруживающий конкретный случай, компилятор все равно не должен выдавать предупреждение о Это. На практике, даже если проблемы обнаружены, разработчики компилятора могут решить не выдавать предупреждение по разным причинам. Некоторые предупреждения относятся к редким крайним случаям, поэтому не стоит их выдавать. Некоторым предупреждениям присуща частота «ложных срабатываний», что приводит к тому, что разработчики жалуются на сообщения об ошибках поставщику компилятора о ненужных предупреждениях, поэтому компилятор по умолчанию настроен так, чтобы их не выдавать.
Следующее требование для выдачи предупреждения - это то, что пользователь компилятора должен выбрать отображение предупреждений. Благодаря яростному лоббированию производителей со стороны разработчиков - большинство современных компиляторов настроены ПО УМОЛЧАНИЮ, поэтому они выдают относительно небольшое количество предупреждений. Поэтому разработчикам, которым требуется максимально возможная помощь от компилятора, необходимо явно включить его. Например, используя -Wall
параметры с gcc и clang.
person
Peter
schedule
30.06.2019
x << 3
? Потому что левый операндx
может быть подписанным или беззнаковым. Стандарт не ограничивает, чтоx
должен быть только беззнаковым типом, то есть это может быть подписанный тип, то есть он может содержать отрицательные значения. - person Achal   schedule 29.06.2019y = z << -4;
(ваше последнее предложение). Компилятор пытается помочь, но не запускает код, чтобы определить, всегда лиx
отрицательно. Он может даже не знать, если значение дляx
вводится пользователем во время выполнения. - person Weather Vane   schedule 29.06.2019