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

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

Если оценка выражения вызывает поведение undefined в C, и выражение всегда оценивается, когда программа выполняется (например, если она появляется в начале main), соответствует ли она, если реализация отвергает это во время компиляции? Есть ли разница в C между компиляцией/переводом программы и ее выполнением?

Я знаю, что существуют интерпретаторы для C. Как они обрабатываются стандартом C относительно этой разницы?

Пример (чтение неинициализированных локальных)

int main() {
  int i;
  return i;
}

При запуске на любой стадии выполнения (даже до main) программа может сделать что-то смешное. Но может ли что-то смешное происходить и тогда, когда мы даже не пытались его запустить? Может ли это вызвать переполнение буфера в самом компиляторе?

4b9b3361

Ответ 1

Из проекта C11:

3.4.3 undefined поведение

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

ПРИМЕЧАНИЕ. Возможно, поведение undefined варьируется от полного игнорирования ситуации с непредсказуемыми результатами, поведения во время трансляции или выполнения программы в документальном виде, характерном для (с выдачей диагностического сообщения или без него), до завершения перевода или исполнения (с выдачей диагностического сообщения).

Прекращение перевода упоминается как возможное последствие поведения undefined в (ненормативной) заметке, поэтому эффекты времени компиляции явно не предназначены для исключения. Нормативная часть конечно позволяет это - она ​​позволяет что угодно. Соответствующий компилятор может завершить перевод, если он обнаруживает поведение undefined во время компиляции.

Кроме того, в $4 Соответствие:

Если a '' should или '' не требует требования, которое появляется за пределами ограничения или ограничения времени выполнения, поведение undefined. undefined поведение в этом международном стандарте указывается словами "undefined" или отсутствием какого-либо явного определения поведения. В этих трех различиях нет разницы; все они описывают поведение undefined.

В нормативном определении или в описании соответствия между "временем перевода" и "временем выполнения" не проводится никакого различия. Различия между различными "разновидностями" поведения undefined не различаются.

Кроме того, Отчет об ошибках # 109, отмеченный ouah в Может ли код, который никогда не будет выполняться, вызывает undefined поведение? имеет это в своем ответе:

[...] Если выражение, чья оценка приведет к поведению undefined, появится в контексте, где требуется постоянное выражение, содержащая программа не строго соответствует. Кроме того, если любое возможное выполнение данной программы приведет к поведению undefined, данная программа не будет строго соответствовать.

Соответствующая реализация не должна переводить строго соответствующую программу просто потому, что некоторое возможное выполнение этой программы приведет к поведению undefined. [...]

Это означало бы, что компилятор не может пропустить перевод, если он не может статически определить, что все пути приводят к поведению undefined.

Ответ 2

В стандарте C11, §3.7.1, указывается, что определение термина undefined:

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

2 ПРИМЕЧАНИЕ. Возможное поведение undefined варьируется от полного игнорирования ситуации с непредсказуемым результатов, вести себя во время перевода или выполнения программы документированным образом, характерным для (с выдачей диагностического сообщения или без него), для завершения перевода или выполнения (с выдачей диагностического сообщения).

Поэтому я предполагаю, что вам разрешено статически отклонять программу, содержащую поведение undefined, даже если она действительна.

Ответ 3

Соответствует ли это, если реализация отвергает его во время компиляции?

Это может быть или не быть. Стандарт C говорит об этом в разделе §3.4.3:

C11: 3.4.3 undefined поведение

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

  • ПРИМЕЧАНИЕ. Возможно, поведение undefined варьируется от полного игнорирования ситуации с непредсказуемыми результатами, для ведения во время перевода или выполнения программы документированным образом, характерным для среды (с выпуском или без него диагностического сообщения), для завершения перевода или выполнения (с выдачей диагностического сообщения).

Итак, ответьте на свой вопрос: может ли это вызвать переполнение буфера в самом компиляторе?

Да, это возможно.