We have a very simple bit of code which is giving a warning but seems like it should be fine, and runs fine. We understand that in general there may be issues with order of initialisation between compilation units, but in this case we are initialising with a pointer, so don't understand how order can cause a problem, or how any problems might arise with this code. Note that in the real code we have more complex scenario with structs, but code below shows the basic issue.
EDIT: have removed const qualifiers as they don't affect the warning
file1.c
int foo=42;
file2.c
#include <stdio.h>
extern int foo;
// Clang-Tidy: Initializing non-local variable with non-const expression depending on uninitialized non-local variable 'foo'
int *bar=&foo;
int main() {
printf("%d\n", *bar); // prints '42'
}
Warning is not from gcc
but from clang-tidy
. To reproduce run:
clang-tidy -checks=* file1.c file2.c
clang-tidy is warning about something that just is not a problem: whether foo
is initialized or not does not make a difference in this initializer where only its address is taken.
Furthermore foo
is a global variable, hence it is either statically initialized in the module that defines it or it does not have an initializer and is initialized to 0 by the loader at run time. If the program was compiled as C++, foo
might be initialized at runtime, before main
is called, potentially by running initializer code, but again this does not make a difference as only its address is used in int *bar = &foo;
You should just disable this warning, as explained by Cameron Tacklind .
As others have mentioned, clang-tidy
is telling you precisely what is wrong.
In this case, I think the clincher is the first part of the sentence: "Initializing non-local variable ...".
The particular warning will go away if bar
is declared (and defined) inside main()
:
#include <stdio.h>
extern int foo;
int main() {
int *bar=&foo; // Still warns about const issues
printf("%d\n", *bar);
}
Alternatively, you can ignore the specific rule for those specific lines pretty easily:
#include <stdio.h>
extern int foo;
// NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init)
int *bar=&foo;
int main() {
printf("%d\n", *bar);
}
In Ubuntu 20.04, I create such file1.c and file2.c, use gcc to compile them and run, but I didn't get any warning like you mentioned above, it works just fine.
In addition, in logical, I don't think it will cause any problem.
In C, keyword const
means constant variable , which can not be changed. In your case, foo
is a constant variable, its address is constant as well; you assign its address to another constant pointer variable bar
, so bar
is always pointing to foo
, and both of them are constant variable, which means anytime *bar
is equal to foo
and vice versa.
By the way, maybe you were in rush when post your question, but I still recommend you to add a ;
in the end of const int *bar=&foo
, which resides in file2.c
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.