Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is running a binary generated from a code with "constraint violation" actually undefined behaviour?

Reference: This question

Context: A return statement at the end of main() with no expression, like

 return;

As I read the standard, it appears to be undefined behavior and so I wrote an answer.

However, another answer says, it's not UB.

Where did I go wrong reading or understanding the standard language?


Note: I have seen this thread already, but I cannot conclude.

like image 551
Sourav Ghosh Avatar asked Jan 04 '23 22:01

Sourav Ghosh


2 Answers

Let's assume this context:

int main(void) {
    return;
}

and a hosted implementation.

Note that void main() is not strictly forbidden (an implementation is permitted to permit it), and return; would be perfectly valid within such a definition of main.

First off, this return; is clearly a constraint violation. It violates N1570 6.8.6.4p1:

A return statement without an expression shall only appear in a function whose return type is void.

(It was not a constraint violation in C90; that was changed in C99.)

The standard requires a compiler to issue at least one diagnostic for any program containing a violation of a constraint or syntax rule. Once it's done so, it can then proceed to generate an executable (if the diagnostic is a non-fatal warning).

It's not clear whether there's a general rule that programs with constraint violations have undefined behavior. The standard doesn't say so explicitly. It defines a "constraint" as a

restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted

My own interpretation is that if a constraint is violated, there is no valid interpretation, and thus the behavior is undefined, but there are some who disagree. I'd like to see an explicit statement to this effect in a future standard.

I believe the wording of the C Standard is genuinely ambiguous on this point.

Without such a general rule, it's not clear that the behavior is undefined. After stating the constraint that this code violates, the standard goes on to define the semantics of the return statement:

A return statement terminates execution of the current function and returns control to its caller.

That description could still make sense even in the presence of this constraint violation. It's reasonable to assume, though it's not quite stated, that return; is equivalent to reaching the closing }, which is equivalent to return 0; (this is a special-case rule for main; N1570 5.1.2.2.3).

On the other hand, it's not 100% clear that the description is unambiguous. The argument that return; is equivalent to reaching the closing } is particularly weak. So even in the absence of a general rule, one could argue that the behavior is undefined by omission (there's no definition of the behavior).

The return; is clearly a constraint violation, and in my opinion it has undefined behavior if the implementation produces an executable. Of course a conforming compiler is also permitted to reject the program altogether; in that case, it has no behavior at all.

Bottom line: It's much much much easier to change the return; to return 0; than to answer this question.

I encourage other language lawyers to refute this answer. I've made enough internally inconsistent arguments here that it shouldn't be too difficult.

like image 143
Keith Thompson Avatar answered Jan 13 '23 17:01

Keith Thompson


Answering the title:

Is running a binary generated from a code with “constraint violation” actually undefined behaviour?

I say no because of the definition of undefined behaviour in the standard, emphasis mine:

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’’

§ 4/2

Assuming that violating a constraint means breaking a "shall" or "shall not" requirement that is inside a section marked as "constraint" and it is not otherwise indicated that the violation leads to UB.

As per the context case I agree with Keith Thompson's answer.

like image 37
Daniel Jour Avatar answered Jan 13 '23 18:01

Daniel Jour