I came up with this issue whilst practicing assignment in C. When I try to initialize any variable with it's name(identifier), which doesn't even exist, is not throwing any kind of error.
int x = x;
As far as I know associativity of assignment operator is right to left. So the following code should throw an error whilst i'm initializing a variable with an rvalue which doesn't even exist. Rather, it's assigning some kind of garbage value to it. Why is this happening?
CodePudding user response:
Setting value to be itself is undefined behavior in c standard. After appending compiler option -Winit-self
and warning occurs.
CodePudding user response:
GCC 11.2 does diagnose this if you use -Wuninitialized -Winit-self
.
I suspect int x = x;
may have been used as an idiom1 for “I know what I am doing; do not warn me about x
being uninitialized,” and so it was excluded from -Wuninitialized
, but a separate warning was provided with -Winit-self
.
Note that while the behavior of int x = x;
is not defined by the C standard (if it is inside a function and the address of x
is not taken), neither does it violate any constraints of the C standard. This means a compiler is not required to diagnose the problem. Choosing to issue a warning message is a matter of choices and quality of the C implementation rather than rules of the C standard.
Apple Clang 11.0 does not warn for int x = x;
even with -Wuninitialized -Winit-self
. I suspect this is a bug (a deviation from what the authors would have wanted, if not from the rules of the C standard), but perhaps there was some reason for it.
Consider code such as:
int FirstIteration = 1;
int x;
for (int i = 0; i < N; i)
{
if (FirstIteration)
x = 4;
x = foo(x);
FirstIteration = 0;
}
A compiler might observe that x = 4;
is inside an if
, and therefore reason that x
might not be initialized in foo(x)
. The compiler might be designed to issue a warning message in such cases and be unable to reason that the use of FirstIteration
guarantees that x
is always initialized before being used in foo(x)
. Taking int x = x;
as an assertion from the author that they have deliberately designed the code this way gives them a way to suppress the spurious warning.
Footnote
1 There are several idioms which are used to tell a compiler the author is deliberately using some construction which is often an error. For example, if (x = 3) …
is completely defined C code that sets x
to 3 and always evaluates as true for the if
, but it is usually a mistake as x == 3
was intended. The code if ((x = 3)) …
is identical in C semantics, but the presence of the extra parentheses is an idiom used to say “I used assignment deliberately,” and so a compiler may warn for if (x = 3) …
but not for if ((x = 3)) …
.