Поведение, определяемое реализацией в C - PullRequest
1 голос
/ 01 апреля 2020

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

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

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

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

Ответы [ 3 ]

2 голосов
/ 02 апреля 2020

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

В языке существуют сотни таких случаев. Стандарт содержит краткое изложение большинства из них в Приложении J.3, длина которого составляет ~ 15 страниц.

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

Специфический пример c int i=0; i >> 3 определяется реализацией, потому что стандарт говорит об этом. C17 6.5.7 / 5:

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

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

1 голос
/ 02 апреля 2020

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

Согласно: https://clc-wiki.net/wiki/C_language: Термины: Definition-Definition_behaviour

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

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

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

1 голос
/ 02 апреля 2020

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...