Self-identity of a variable in its definition

The following C ++ program compiles just fine (g ++ 5.4 at least gives a warning when called with -Wall ):

 int main(int argc, char *argv[]) { int i = i; // ! return 0; } 

Even something like

 int& p = p; 

absorbed by the compiler.

Now my question is: why is this initialization legal? Is there any factual precedent or is it just a consequence of the general design of the language?

+5
source share
3 answers

Just because the compiler accepts it (syntactically valid code) does not mean that it has well-defined behavior.

The compiler is not required to diagnose all cases of Undefined Behavior or other classes of problems. The standard gives pretty free hands to accept and translate broken code, based on the assumption that if the results were to be Undefined or pointless, the programmer would not write this code.

So, the absence of warnings or errors from your compiler in no way proves that your program has well-defined behavior. You are responsible for following the language rules. The compiler usually tries to help you by pointing out obvious flaws, but in the end, you have to make sure that your program makes sense.

And something like int i = i; it doesn’t make sense, but it’s syntactically correct, therefore the compiler may or may not warn you, but in any case it’s its right to simply generate garbage (and not inform you about it) because you violated the rules and caused Undefined Behavior.

0
source

I think the essence of your question is why the second identifier is recognized as the identification of the same object as the first, in int i = i; or int &p = p;

This is defined in [basic.scope.pdecl] / 1 of the C ++ 14 standard:

The declaration point for the name immediately after its full declarator and before its initializer (if any), except as noted below. [Example:

 unsigned char x = 12; { unsigned char x = x; } 

Here, the second x initialized with its own (undefined) value. -end example]

The semantics of these operators covers other threads:

Note. The given example differs in semantics from int i = i; , because not UB evaluates the uninitialized unsigned char , but UB evaluates the uninitialized int .

As noted in a related topic, g ++ and clang may give warnings when they detect this.


Regarding the rationale for the scope rule: I don’t know for sure, but the scope rule existed in C, so maybe it just made its way in C ++, and now it would be strange to change it.

If we said that the declared variable does not enter the scope for its initializer, then int i = i; can make the second i find i from the outer region, which will also be confusing.

0
source

This is a side effect of the rule that the name is in scope immediately after its declaration. There is no need to complicate this simple rule to prevent code writing, which is sheer stupidity.

0
source

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


All Articles