在 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.\nRun Code Online (Sandbox Code Playgroud)\n人们不可能使用此警告来推理他的代码。
\nclang 文档有以下内容:
\n\n\n由于 -Weverything 启用每个诊断,因此我们通常不建议使用它。-Wall -Wextra 对于大多数项目来说是更好的选择。使用 -Weverything 意味着更新编译器更加困难,因为您\xe2\x80\x99 暴露于实验诊断,其质量可能低于默认诊断。如果您确实使用 -Weverything,那么我们建议您在添加到 Clang 时解决所有新的编译器诊断问题,方法是修复它们找到的所有内容,或者使用相应的 Wno- 选项显式禁用该诊断。
\n
在这种情况下,我该如何“修复他们发现的一切”?
\n设置-Wno-unsafe-buffer-usage有效,但这是一个丑陋的解决方案。\n它给 Makefile 增加了混乱,感觉像是作弊。
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外观是你唯一的选择。
这个警告似乎基本上没有记录(这可能表明它最好被禁用)。现有信息表明您没有错过任何事情;根本不可能在不触发的情况下编译完整的 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。)