Is running a binary created using code with the "restriction of restrictions" behavior really undefined?

Link: This Question

Context: return at the end of main() without expression, e.g.

  return; 

When I read the standard, it looks like undefined behavior , and so I wrote the answer .

However, another answer says that it is not UB.

Where did I misread or understand the standard language?


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

+5
source share
4 answers

Assume this context:

 int main(void) { return; } 

and hosted version.

Please note that void main() not strictly forbidden (implementation is allowed to resolve it), but return; will be completely correct in such a definition of main .

The first is return; , obviously, is a violation of the restriction. It violates N1570 6.8.6.4p1:

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

(This was not a violation of the restriction in C90, which was changed to C99.)

The standard requires that the compiler issue at least one diagnostic for any program that contains a violation of a restriction rule or syntax. After that, it can continue to generate an executable file (if the diagnosis is a non-fatal warning).

It is unclear whether there is a general rule that programs with violation of restrictions have undefined behavior. The standard does not say so explicitly. He defines "restriction" as

a restriction, syntactic or semantic, with which to interpret the presentation of language elements

My own interpretation is that if the restriction is violated, then there is no valid interpretation, and therefore the behavior is undefined, but there are some who disagree. I would like to see an explicit statement about this in the future standard.

I believe that the wording of the C-standard is really ambiguous in this matter.

Without such a general rule, it is not clear that the behavior is undefined. After specifying a restriction that this code violates, the standard continues to define the semantics of the return :

The return terminates the current function and returns control to its caller.

This description may make sense even if there is a violation of the restriction. It is reasonable to assume, although not entirely clear, that return; 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 is not 100% clear that the description is unambiguous. The argument is that return; equivalent to achieving closure } , is particularly weak. Thus, even in the absence of a general rule, it can be argued that the behavior is undefined by skipping (there is no definition of behavior).

return; is clearly a violation of the restriction, and in my opinion, it has undefined behavior if the implementation creates an executable file. Of course, the corresponding compiler is also allowed to completely abandon the program; in this case, he has no behavior at all.

Bottom line: significantly easier to change return; on return 0; than to answer this question.

I urge other language advocates to refute this answer. I have made fairly intrinsically contradictory arguments here that this should not be too complicated.

+7
source

Responding to the headline:

Does binary code generated from code with "violation of restrictions" actually have undefined behavior?

I say no due to the definition of undefined behavior in the standard, emphasize mine:

If `` should or '' should not require the appearance of a time limit or a time limit, the behavior is undefined. undefined behavior is specified differently in this International Standard by the words 'undefined behavior or by omitting any explicit definition of behavior. There is no difference in the three; they all describe the behavior of' undefined

ยง 4/2

Assuming that a violation of a restriction means a violation of the requirement "must" or "should not", which is located inside the section labeled as "restriction", and it is not otherwise indicated that the violation leads to UB.

In accordance with the context, I agree with Keith Thompson's answer.

0
source

The standard does not define the behavior of code that contains a restriction violation. Therefore, the behavior is undefined.

Saying that the code containing the violation of the restriction is well defined, it is equivalent to the fact that all restrictions in the standard can be ignored, which is absurd.

0
source

As a real scenario, when a program with violation of restrictions can cause Undefined Behavior, consider a build system that does not delete output files if / until it replaces them. When a valid program is submitted, it creates an executable file with a specific name, and when an invalid program is submitted, the program leaves the old file unchanged. Since the source code that was used to create the remaining executable file may not be related to the current source code, the behavior of the executable file may be arbitrarily different from everything in the current source file.

Ideally, the implementation will try to prevent accidental execution of such code, but if the C compiler is just a small part of a larger build system, the compiler may not have control over such problems, and I doubt that the authors of the Standard wanted to say that build systems that do not allowed the compiler to delete or invalidate the executable file (of which it knows nothing), cannot post the corresponding C implementations.

0
source

Source: https://habr.com/ru/post/1261281/


All Articles