Ответ 1
Оба правильные. Определенное поведение определяется определенным типом неуказанного поведения.
Раздел 3.4.1 цитирования стандарт C, который определяет "поведение, определяемое реализацией":
1 поведение, определяемое реализацией
неопределенное поведение, когда каждая реализация документирует, как делается выбор
2 ПРИМЕР Пример реализации, определяемого реализацией, - это распространение бит высокого порядка когда целое число со знаком смещено вправо.
Из раздела 3.4.4, определяющего "неуказанное поведение":
1 неуказанное поведение
использование неопределенного значения или другое поведение, когда это Международный стандарт предоставляет две или более возможности и налагает никакие дополнительные требования к которым не выбраны ни в одном случае
2 ПРИМЕР Пример неуказанного поведения - это порядок, в котором оцениваются аргументы функции.
Что касается GCC, вы всегда получите тот же ответ, потому что операция определена реализацией. Он реализует сдвиг вправо отрицательных чисел с помощью расширения знака
Из документации GCC:
Результаты некоторых побитовых операций с целыми знаками (C90 6.3, C99 и C11 6.5).
Поразрядные операторы действуют на представление значения, включая как биты знака и значения, где бит знака считается непосредственно над битом ценности с наивысшим значением. Подпись
>>
действует отрицательные числа с расширением знака.Как расширение языка C, GCC не использует заданную широту в C99 и C11 только для обработки определенных аспектов подписанного
<<
как undefined. Однако-fsanitize=shift
(и-fsanitize=undefined
) будет диагностировать такие случаи. Они также диагностированы, где постоянная требуется выражение.