Поведение, определяемое реализацией в C

Пожалуйста, не могли бы вы привести пример поведения, определяемого реализацией в C?

Например, из стандарта я знаю, что «поведение, определяемое реализацией, — это распространение старшего бита, когда целое число со знаком сдвигается вправо».

Можете ли вы объяснить мне значение примера и привести пример?

Я понимаю, что int i; i >> 3. Но почему это определяется реализацией?


person Epik    schedule 01.04.2020    source источник


Ответы (3)


Определение поведения, определяемого реализацией в C, - это когда компилятору остается что-то решать, и компилятор документирует, какой выбор он сделал.

Таких падежей в языке сотни. Стандарт содержит краткое изложение большинства из них в Приложении J.3, которое занимает около 15 страниц.

Конкретный пример int i; i >> 3 имеет неопределенное поведение, поскольку переменная не инициализирована.

Конкретный пример int i=0; i >> 3 определяется реализацией, потому что так сказано в стандарте. С17 6.5.7/5:

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

В данном конкретном случае это зависит от того, выбирает ли компилятор арифметический сдвиг или инструкцию логического сдвига из набора инструкций ЦП. Это означает, что стандарт не одобряет архитектуры, в которых отсутствует арифметический сдвиг. Хотя на практике подавляющее большинство процессоров способны выполнять арифметический сдвиг, даже RISC.

person Lundin    schedule 02.04.2020

Это определено реализацией, потому что комитет по стандартам C отказался определять, что должно произойти. Причина, по которой они это сделали, заключается в том, что в таких обстоятельствах разные ЦП делают разные вещи, а идеал C (в интересах быстрого выполнения) заключается в том, чтобы не делать слишком много абстракции между исходным кодом C и кодами операций, работающими на ПРОЦЕССОР.

Они могли бы определить стандартное поведение, но тогда на некоторых ЦП потребовалось бы, чтобы компиляторы генерировали загрузку кода, чтобы компенсировать тот факт, что собственные коды операций ЦП не обеспечивают такого стандартизированного поведения. Хотя это вполне возможно, это неизбежно будет не очень эффективным.

Другие, без сомнения, смогут указать на более авторитетные версии этого объяснения!

person bazza    schedule 02.04.2020

Любой код, основанный на поведении, определяемом реализацией, гарантированно работает только на определенной платформе и/или компиляторе. Портативные программы должны стараться избегать такого поведения.

Согласно: https://clc-wiki.net/wiki/C_language:Terms:Implementation-defined_behaviour

Это также дает другой пример:

int *o = malloc(0 * sizeof *o);

может привести к тому, что o будет либо NULL, либо уникальным указателем (как указано в 7.20.3 стандарта C99).

person JohannesB    schedule 02.04.2020