简体   繁体   English

Clang-Tidy:根据未初始化的非局部变量、C 指针引用,用非常量表达式初始化非局部变量

[英]Clang-Tidy: Initializing non-local variable with non-const expression depending on uninitialized non-local variable, C pointer reference

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编辑:已删除 const 限定符,因为它们不会影响警告

file1.c文件1.c

int foo=42;

file2.c文件2.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 .警告不是来自gcc而是来自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. clang-tidy警告一些不是问题的东西: foo是否被初始化在这个只取其地址的初始化程序中没有区别。

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.此外foo是一个全局变量,因此它要么在定义它的模块中静态初始化,要么没有初始化程序并在运行时由加载程序初始化为 0。 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;如果程序被编译为 C++, foo可能会在运行时初始化,在调用main之前,可能通过运行初始化代码,但这同样没有区别,因为在int *bar = &foo;只使用了它的地址int *bar = &foo;

You should just disable this warning, as explained by Cameron Tacklind .您应该禁用此警告,如Cameron Tacklind 所述

As others have mentioned, clang-tidy is telling you precisely what is wrong.正如其他人所提到的, clang-tidy准确地告诉您出了什么问题。

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() :如果在main()声明(和定义) bar则特定警告将消失:

#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.在 Ubuntu 20.04 中,我创建了这样的 file1.c 和 file2.c,使用 gcc 编译它们并运行,但是我没有像上面提到的那样收到任何警告,它工作得很好。

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.在 C 中,关键字const表示常量变量,不能更改。 In your case, foo is a constant variable, its address is constant as well;在你的情况下, foo是一个常量变量,它的地址也是常量; 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.您将其地址分配给另一个常量指针变量bar ,因此bar始终指向foo ,并且它们都是常量变量,这意味着任何时候*bar等于foo ,反之亦然。

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 .const int *bar=&foo的末尾,它驻留在file2.c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM