Reputation: 303
A simple program:
int main()
{
long i = i;
return 0;
}
Compiling as C gives no errors and no warnings.
$ gcc -Wall -Wextra -pedantic 1.c
Compiling as C++ gives a warning:
$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
long i = i;
In both cases variable i seems to be 0, although in c++ it could be uninitialized. I actually made such a typo in one of my functions and it was quite hard to find it. What can I do to avoid this? I'd expect at least a warning. Moreover, Clang doesn't give any warning in either case (c or c++). Is there a specific part of the standard that says anything about this behavior?
Edit: Having tried something similar:
$ cat 1.c
int main(void)
{
int k = k + 0;
int i = i + 1;
return 0;
}
The warning (in C) is generated only for "i".
$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
int i = i + 1;
Upvotes: 29
Views: 927
Reputation: 241671
For GCC compiling C programs, you need to add the compiler flag -Winit-self
. (You also need -Wall
or -Wuninitialized
, see below.) For GCC compiling C++ programs, this flag is implied by -Wall
but for C it needs to specified explicitly; it is not part of -Wextra
either.
For Clang, the situation is slightly more interesting. In the snippet in the OP, Clang does not produce any diagnostic. However, with the slightly different snippet supplied in the GCC manual below, a diagnostic is provided:
int f() {
int i = i;
return i;
}
The difference is that in the above snippet, the (uninitialized) value of i
is actually used. Apparently, in the original code Clang detected that the variable was useless and eliminated it as dead code before applying the diagnostic.
In Clang, the diagnostic is triggered by -Wuninitialized
, which is enabled by -Wall
as in GCC.
Here's an excerpt from the GCC manual:
-Winit-self
(C, C++, Objective-C and Objective-C++ only)Warn about uninitialized variables that are initialized with themselves. Note this option can only be used with the
-Wuninitialized
option.For example, GCC warns about
i
being uninitialized in the following snippet only when-Winit-self
has been specified:int f() { int i = i; return i; }
This warning is enabled by
-Wall
in C++.
As the excerpt indicates, -Wuninitialized
is also required. In both C and C++, -Wall
implies -Wuninitialized
. However, note that many uninitialized uses will not be detected unless some optimization level is also requested. (That doesn't apply to -Winit-self
, as far as I know. It can be detected without optimization.)
Irritatingly, when you unmark a question as a duplicate, the previously-marked duplicates disappear. I unmarked it because none of the duplicates actually answered the question in the body; I also edited the title.
For reference, here are the original duplicates, which may be of interest:
Why does the compiler allow initializing a variable with itself?
Why is this initialization accepted by the c++ compiler? static int x = x;
Upvotes: 19
Reputation: 229058
The combination of -Wall -Winit-self
seems to add this diagnostic:
$ gcc -Wall -Winit-self t.c
t.c: In function ‘main’:
t.c:3:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
long i = i;
^
Upvotes: 4
Reputation: 195
It is basically:
int i;
i = i;
in which i
is an uninitialized value.
Upvotes: 4