繁体   English   中英

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

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

我们有一段非常简单的代码,它发出警告,但看起来应该没问题,并且运行正常。 我们知道通常编译单元之间的初始化顺序可能存在问题,但在这种情况下,我们使用指针进行初始化,因此不了解顺序如何导致问题,或者此代码如何可能出现任何问题。 请注意,在实际代码中,我们有更复杂的结构场景,但下面的代码显示了基本问题。

编辑:已删除 const 限定符,因为它们不会影响警告

文件1.c

int foo=42;

文件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'
}

警告不是来自gcc而是来自clang-tidy 要重现运行:

clang-tidy -checks=* file1.c file2.c

clang-tidy警告一些不是问题的东西: foo是否被初始化在这个只取其地址的初始化程序中没有区别。

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

您应该禁用此警告,如Cameron Tacklind 所述

正如其他人所提到的, clang-tidy准确地告诉您出了什么问题。

在这种情况下,我认为关键是句子的第一部分:“初始化非局部变量......”。

如果在main()声明(和定义) bar则特定警告将消失:

#include <stdio.h>

extern int foo;

int main() {
  int *bar=&foo; // Still warns about const issues

  printf("%d\n", *bar);
}

或者,您可以很容易地忽略这些特定行的特定规则:

#include <stdio.h>

extern int foo;

// NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init)
int *bar=&foo;

int main() {
  printf("%d\n", *bar);
}

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

另外,在逻辑上,我认为这不会造成任何问题。

在 C 中,关键字const表示常量变量,不能更改。 在你的情况下, foo是一个常量变量,它的地址也是常量; 您将其地址分配给另一个常量指针变量bar ,因此bar始终指向foo ,并且它们都是常量变量,这意味着任何时候*bar等于foo ,反之亦然。

顺便说一句,也许您在发布问题时很着急,但我仍然建议您添加; const int *bar=&foo的末尾,它驻留在file2.c

暂无
暂无

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

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