If an evaluation of an expression causes undefined behavior in C, and the expression is always evaluated when the program is executed (for example if it appears at the start of main
), is it conforming if an implementation rejects it at compile time? Is there a difference in C between compiling/translating a program and executing it?
I know that there are interpreters for C. How are they handled by the C standard regarding this difference?
Example (reading uninitialized local)
int main() { int i; return i; }
When running it, at any stage of the execution (even before main
is called), the program can do something funny. But can something funny also happen when we haven't even tried to run it? Can it cause a buffer overflow in the compiler itself?
Whenever a C program file is compiled and executed, the compiler generates some files with the same name as that of the C program file but with different extensions.
If you only have a ". c" file, then you don't have a program. You must compile the program first to make an executable, and then you must run the program to get its output.
In a compiled language, the target machine directly translates the program. In an interpreted language, the source code is not directly translated by the target machine. Instead, a different program, aka the interpreter, reads and executes the code.
From a C11 draft:
3.4.3 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Terminating the translation is mentioned as a possible consequence of undefined behavior in the (non-normative) note, so compile-time effects are clearly not intended to be excluded. The normative part certainly allows it - it allows anything. So conforming compiler can terminate the translation if it detects undefined behavior during compilation.
Additionally, in $4 Conformance:
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.
There is no distinction made either in the normative definition or in the conformance description between "translation time" and "execution time". No difference is made between different "varieties" of undefined behavior.
Additionally, Defect Report #109 pointed out by ouah in Can code that will never be executed invoke undefined behavior? has this in its response:
[...] If an expression whose evaluation would result in undefined behavior appears in a context where a constant expression is required, the containing program is not strictly conforming. Furthermore, if every possible execution of a given program would result in undefined behavior, the given program is not strictly conforming.
A conforming implementation must not fail to translate a strictly conforming program simply because some possible execution of that program would result in undefined behavior. [...]
This would indicate that a compiler cannot fail a translation if it cannot statically determine that all paths lead to undefined behavior.
In the C11 standard, §3.7.1 it is stated, under the definition of the term undefined behavior:
undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
So I guess you are allowed to statically reject a program which contains undefined behavior, even if it's valid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With