如何修复代码以避免警告 -Wunsafe-buffer-usage

14 c clang compiler-warnings

在 clang 16.0 之前,我能够使用 -Weveything 毫无问题地编译所有项目,\n修复我的代码并注意此选项给出的(有用的)警告。\n但是,似乎添加了 -Wunsafe-buffer-usage在版本 16 中(我的系统最近更新到了它)\n如果没有得到关于正在使用的任何指针的大量无用警告,则不可能编译任何项目,请参阅下面的最小示例:

\n
$ cat main.c\n#include <stdio.h>\n\nint main(int argc, char **argv) {\n    if (argc != 2) {\n        return 0;\n    }\n    printf("argv[1] = %s\\n", argv[1]);\n}\n\n$ clang -Weverything main.c\nmain.c:3:27: warning: 'argv' is an unsafe pointer used for buffer access [-Wunsafe-buffer-usage]\nint main(int argc, char **argv) {\n                   ~~~~~~~^~~~\nmain.c:7:30: note: used in buffer access here\n    printf("argv[1] = %s\\n", argv[1]);\n                             ^~~~\n1 warning generated.\n
Run Code Online (Sandbox Code Playgroud)\n

人们不可能使用此警告来推理他的代码。

\n

clang 文档有以下内容:

\n
\n

由于 -Weverything 启用每个诊断,因此我们通常不建议使用它。-Wall -Wextra 对于大多数项目来说是更好的选择。使用 -Weverything 意味着更新编译器更加困难,因为您\xe2\x80\x99 暴露于实验诊断,其质量可能低于默认诊断。如果您确实使用 -Weverything,那么我们建议您在添加到 Clang 时解决所有新的编译器诊断问题,方法是修复它们找到的所有内容,或者使用相应的 Wno- 选项显式禁用该诊断。

\n
\n

在这种情况下,我该如何“修复他们发现的一切”?

\n

设置-Wno-unsafe-buffer-usage有效,但这是一个丑陋的解决方案。\n它给 Makefile 增加了混乱,感觉像是作弊。

\n

dbu*_*ush 14

我在 godbolt 的 16.0.0 版本中多次尝试解决此特定警告,即 argv != NULL && argv[1] != NULL在调用 之前进行检查printf,但没有成功。事实上,即使是这个特定的检查也触发了警告。

鉴于文档明确建议不要使用-Weverything,如果您确实使用相应的-Wno-选项来处理无用的警告,并且不清楚如何解决此警告(我无法找到有关此选项的文档),添加-Wno-unsafe-buffer-usage可能是最好的选择。

并基于 LLVM 讨论板评论中的链接:https://discourse.llvm.org/t/rfc-c-buffer-hardening/65734/85

该警告目前在一个无法绕过的地方触发。int main(int argc, char const** argv)

在这种情况下似乎无法消除警告。所以使用-Wno-unsafe-buffer-usage外观是你唯一的选择。

  • @lucas.mior:关于“即使在程序的核心方面也无法修复其所警告的代码的警告有什么意义?”:正如文档所述,“-Weverything”中的附加警告是实验性的。实验的目的是获得反馈:Clang 维护者测试警告选项,看看它们有多有用以及它们可能存在哪些问题。使用 `-Weverything` 的人应该向 Clang 维护者报告问题,包括演示问题的示例代码,以便 Clang 维护者可以考虑改进。这就是我想说的。 (8认同)
  • 是的,但是文档说“要么通过修复他们发现的所有内容,要么显式禁用......”即使在程序的如此核心方面也无法修复其所警告的代码的警告有什么意义? (6认同)
  • @lucas.mior 回复:*“即使在程序的如此核心方面也无法修复其所警告的代码的警告有什么意义”*我认为这是“实验诊断”的一部分。 (4认同)
  • @lucas.mior 我认为在这种情况下你可能别无选择,只能忽略。似乎[你不是唯一一个](/sf/ask/5353714481/)对此选项遇到麻烦的人。 (3认同)
  • @yvs2014:所以呢?事实上,报告“main”的“argv”是可以反馈给 Clang 开发人员的信息。此外,链接中的第一项给出了“-Weverything”的另一个原因:对其报告的所有诊断手动使用一次,自己评估每个诊断,修复实际问题,但将其保留在常规构建中。 (3认同)
  • @dbush 和 EricPostpischil 也许这就是理论上的要点,但实际上我在 llvm 的 github 中打开了一个关于它的问题,它被关闭,因为无法修复,“原因”是我在问题中复制的文档引用(其中没有解释*为什么*有人想要使用该警告)。从 clang 18.0 开始,这个警告仍然存在,所以我想知道除了“实验性”之外是否还有任何实际原因包含诊断。 (2认同)
  • @yvs2014:出于安全性、可靠性或其他目标,有些人可以从对代码的更严格审查中受益。如果您不认为以这种方式使用“-Weverything”的努力会给您带来净收益,那就这样吧。但这并不能否认使用它来造福他人的理由的存在。 (2认同)

Gle*_*len 8

这个警告似乎基本上没有记录(这可能表明它最好被禁用)。现有信息表明您没有错过任何事情;根本不可能在不触发的情况下编译完整的 C 程序。如果您希望在编译整个 C 程序(包括 )时使用-Weverythingwith ,则似乎必须禁用此警告。-Werrormain

感谢@yvs2014 在评论中提供此链接:https://discourse.llvm.org/t/rfc-c-buffer-hardening/65734/85

在该讨论线程中建议 (1) 此警告实际上适用于 C++ 代码,通常不应处理原始指针,并且不适用于 C 代码;(2) 理论上它可以用于 C 代码,该代码使用一些库或 API 来抽象出原始指针的使用;(但在编译该库的实现时不可能使用它);(3) 编译时绝对不能使用main

我质疑这种设计选择的智慧,但它就是这样(而且他们确实明确警告不要使用-Weverything。)