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;
GCC 4.3+ now has -Q --help=warnings , and you can even specify --help=warnings,C to just print out the C related warnings.
gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.
If -Wfatal-errors is also specified, then -Wfatal-errors takes precedence over this option. Inhibit all warning messages. Make all warnings into errors.
You can make all warnings being treated as such using -Wno-error. You can make specific warnings being treated as such by using -Wno-error=<warning name> where <warning name> is the name of the warning you don't want treated as an error. If you want to entirely disable all warnings, use -w (not recommended).
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?
gcc failing to warn of uninitialized variable
Why is this initialization accepted by the c++ compiler? static int x = x;
Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
It is basically:
int i; i = i;
in which i
is an uninitialized value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With