如何解决Clang-Tidy:根据未初始化的非局部变量、C 指针引用,用非常量表达式初始化非局部变量
我们有一段非常简单的代码,它发出警告,但看起来应该没问题,并且运行正常。我们知道通常编译单元之间的初始化顺序可能存在问题,但在这种情况下,我们使用指针进行初始化,因此不了解顺序如何导致问题,或者此代码如何可能出现任何问题。请注意,在实际代码中,我们有更复杂的结构场景,但下面的代码显示了基本问题。
编辑:删除了常量限定符,因为它们不影响警告
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'
}
警告不是来自gcc
,而是来自clang-tidy
。重现运行:
clang-tidy -checks=* file1.c file2.c
解决方法
在 Ubuntu 20.04 中,我创建了这样的 file1.c 和 file2.c,使用 gcc 编译它们并运行,但是我没有收到像上面提到的任何警告,它工作正常。
另外,在逻辑上,我认为这不会造成任何问题。
在C中,关键字const
表示常量,不能改变。在你的例子中,foo
是一个常量变量,它的地址也是常量;您将其地址分配给另一个常量指针变量bar
,因此bar
始终指向foo
,并且它们都是常量变量,这意味着任何时候*bar
都等于foo
反之亦然。
顺便说一句,也许您在发布问题时很着急,但我仍然建议您在位于 ;
的 const int *bar=&foo
的末尾添加一个 file2.c
。
为什么你应该听 clang-tidy
我明白,你问为什么 clang-tidy 给你警告......这是因为 clang 和 gcc 会错过我给你的例子,而 clang-tidy 会抓住它。
所以不要 了解秩序如何导致问题,或任何问题如何可能 出现此代码。
这不是“顺序”的问题,而是编译器是否会看到这个问题的问题。链接器将解决该问题。
可能出错的答案:
以下是完全可以接受的
clang -Wall -o foo file1.c file2.c
file1.c:
#include <stdio.h>
extern const struct FOO {
char *value;
} foo;
const struct FOO *bar = &foo;
int main() {
printf("%s\n",bar->value);
return 0;
}
file2.c:
int foo[] = { 'H','e','l','o',0xDEADBEEF };
您在 file2.c 中所做的将完全由 file1.c 声明信任,无需检查。
上面的例子展示了什么:
问题是上面的代码编译得完全干净,但它是一个示例,说明如何在整个代码库中引入内存错误。运行 foo
将产生分段错误,因为您的 struct FOO *bar
现在在运行时指向 file2.c 中完全有效的全局 int foo
数组。
手头更大的问题
C 允许您将任何内容指向任何内容。如果您没有通过创建结构定义和使用头文件并创建适当的策略来使用某种类型的方案来声明全局变量来避免运行时错误。
个人笔记
停止这样编程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。