Home > other >  Why initializing a value by itself is not throwing any error in C?
Why initializing a value by itself is not throwing any error in C?

Time:03-13

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)) ….

  • Related