Подтвердить что ты не робот

"-1 >> 5;" неуказанное поведение в C?

C11 §6.5.7 Пункт 5:

Результатом E1 >> E2 является E1 смещение по правому краю E2. Если E1 имеет неподписанный тип или если E1 имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью фактор E1 / 2*^E2. Если E1 имеет подписанный тип и отрицательный значение, результирующее значение определяется реализацией.

Но в справочном документе viva64 указано:

int B;
B = -1 >> 5; // unspecified behavior

Я запустил этот код на GCC и всегда дает вывод -1.

Итак, стандарт говорит, что "Если E1 имеет тип со знаком и отрицательное значение, результирующее значение определяется реализацией" , но этот документ говорит, что -1>>5; - это неопределенное поведение.

Итак, Is -1>>5; неуказанное поведение в C? Что правильно?

4b9b3361

Ответ 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) будет диагностировать такие случаи. Они также диагностированы, где постоянная требуется выражение.

Ответ 2

"Неизвестное поведение" и "реализация" не противоречат друг другу. Это просто означает, что стандарт C не указывает, что должно произойти, и что различные реализации могут выполнять то, что они считают "правильным".

Выполняя его несколько раз на одном компиляторе, и получение того же результата означает только то, что этот конкретный компилятор согласован. Вы можете получить разные результаты в другом компиляторе.