Может ли реализация указать неопределенное поведение

3.4.1
1 поведение, определяемое реализацией
неопределенное поведение, когда каждая реализация документирует, как делается выбор

Может ли реализация указать, что поведение, определяемое реализацией, является неопределенным поведением в случаях, когда неопределенное поведение является возможным результатом?

Например:

6.3.1.3 Целочисленные и беззнаковые целые числа
3 В противном случае новый тип подписан и значение не может быть представлено в нем; либо результат определяется реализацией, либо генерируется сигнал, определяемый реализацией.

До тех пор, пока он документирован, может ли этот результат быть неопределенным в результате реализации и вызвать неопределенное поведение, или он должен иметь определенный результат для этой реализации?

Нет, семантически это невозможно. Неопределенное поведение – это то, что термин говорит, поведение, которое не определено стандартом. Если стандартное требование определяет поведение реализации, оно явно запрашивает реализацию, чтобы указать, что она делает, когда возникает определенная ошибка.

неопределенное поведение

поведение при использовании непереносимой или ошибочной программной конструкции или ошибочных данных, для которых настоящий международный стандарт не налагает никаких требований

Таким образом, реализация могла бы сказать: «при этом и в этих обстоятельствах эта реализация вызывает сигнал о рекламе», но она не может сказать «в этом и в этих обстоятельствах мы не говорим вам, что делаем» .

Не мистифицируйте неопределенное поведение как нечто, что произойдет или даже как что-то, что можно определить.

Вы можете найти более подробное объяснение того, что подразумевается под определением «реализация» в « Обосновании» – не стандартном документе как таковом , а хорошей ссылке.

В главе 1.6 Определение терминов :

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

Вы не можете принять «разумное решение по кодированию», основанное на неопределенном поведении.

Часто задаваемые вопросы по C (опять же, не стандартная, но хорошо известная ссылка) также понятны :

определение реализации: реализация должна выбрать некоторое поведение; он может не скомпилировать программу. ( Программа, использующая конструкцию, неверна. ) Выбор должен быть документирован. Стандарт может указывать набор допустимых вариантов поведения, из которых можно выбрать, или он не может налагать особых требований

Никакие неопределенные и определенные реализацией поведения не являются ошибками – компилятор не может не выполнить перевод. Они призваны дать варианты реализации для создания оптимального кода для целевой среды.

Присвоение целых чисел более мелким типам является чем-то странным, поскольку в стандарте четко признается, что некоторые реализации могут ловушку, но – однозначно – это требует, чтобы захват соблюдал правила сигналов; решение навязать это требование здесь, но не в другом месте, несколько любопытно, поскольку во многих случаях это будет мешать тому, что в противном случае было бы простой оптимизацией – заменой целой целой знаковой переменной, тип которой короче, чем int , и адрес которой никогда не принимался, с int .

Тем не менее, по тем или иным причинам, авторы стандарта ушли с пути, чтобы запретить эту оптимизацию. [Примечание. Если бы я отвечал за стандарт, я бы указал, что явное приведение к более короткому целочисленному типу даст значение, которое при приведении к неподписанному типу одного и того же размера даст тот же результат, что и значение значения непосредственно при каждом такое значение существует, но что хранилище негабаритного значения непосредственно для lvalue без броска не будет таким образом ограничено; Я не писал стандарт, хотя].

Это иронично, на самом деле: данный:

 uint64t signedpow(int32_t n, uint32_t p) { uint64_t result; while(p--) { n*=n; result+=n; } return result; } uint64t unsignedpow(uint32_t n, uint32_t p) { uint64_t result; while(p--) { n*=n; result+=n; } return result; } 

На платформе, где int – 32 бита, последний определил семантику для всех значений n и p , в то время как первая не будет, но на платформе, где int – 64 бита, обратное будет верно. Компилятор для типичной 64-битной платформы, которая не захотела тратить код на какое-то другое определенное поведение, потребовалась бы стандартом для маскировки и подписывания подписанного n после каждого умножения, но с некоторыми значениями без знака компилятор мог бы делать все, что угодно, в том числе возвращаться вовремя и притворяться, что никакая реализация никогда не обещала всегда выполнять полуразмерные неподписанные множители в соответствии с модульной арифметикой.

Согласно стандарту C11 , глава 3.4.1,

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

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

Таким образом, каждая реализация должна сделать выбор. В противном случае это не будет соответствовать . Таким образом, мы можем сказать, что он должен иметь определенный результат для этой реализации. Это может быть либо нижеследующее

  • определенное поведение, специфичное для этой реализации, которое будет выполняться, если команда встречается.
  • определенный сигнал, который будет подвергаться риску, если возникнет проблема. (В основном, говоря, что нельзя обрабатывать.)

Связанные с:

  1. Из документа C99 Обоснование» , глава 3 ( основное внимание )

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

Теперь никто не может принимать «осмысленные решения по кодированию», основанные на неопределенном поведении.

  1. Из С FAQ , Вопрос 11.33,

определение реализации: реализация должна выбрать некоторое поведение; он может не скомпилировать программу. (Программа, использующая конструкцию, неверна.) Выбор должен быть документирован. Стандарт может указывать набор допустимых вариантов поведения, из которых можно выбрать, или он не может налагать особых требований.

Первое предложение содержит обязательно , как я упоминал ранее в своем ответе.