怎么让编译器忽略警告
❶ c++编译时出现警告,怎么办
C++ 编译时出现警告,说明编译器在编译过程中发现了一些可能不正确或者不安全的代码,但并不影响程序的运行。对于警告,我们需要具体分析具体对待。
如果警告不影响程序的正确性和安全性,可以选择忽略。
如果警告可能会导致程序的正确性和安全性受到影响,那么我们需要修改源代码,消除警告。
修改的方法有以下几种:
修改代码,使得程序逻辑更加清晰,减少警告出现的可能性。
添加注释或者代码,明确说明某些操作的不确定性,从而消除警告。
使用编译器的警告选项,关闭或者抑制某些警告。
对于具体的警告信息,我们需要根据编译器的提示来进行修改。例如,如果编译器提示缺少头文件,那么我们需要在程序的开头添加相应的头文件;如果编译器提示某个变量的使用未定义,那么我们需要在变量定义之前添加相应的声明。
总的来说,对于 C++ 编译时的警告,我们需要根据具体情况来决定是否需要修改源代码,以及如何修改。
❷ 5分钟掌握cmake(19): 使用 SYSTEM 关键字忽略三方库头文件的编译警告
1年前,@大缺弦 在 CMake 官方仓库中为 add_subdirectory() 增加了 SYSTEM 关键字 (FetchContent_Declare 也加了, 不过我还没用过这个函数), 并在 CMake 3.25 版本中正式发布。 本文提供一个简单的例子, 展示个人对 add_subdirectory(xxx SYSTEM) 的理解。
2. 复现工程代码
2.1 目录结构
有如下的目录结构:在自己的工程example 下, 引入了第三方的工程 hello: 可以是完全基于源代码的三方工程, 也可以是头文件 + 库文件的形式, 异或是 header-only 的三方库。 即:
hello 子目录是别人工程的源码:
或如下的目录结构: hello 子目录是头文件 + 预编译好的库 + CMakeLists.txt:
或者 header-only 形式:
无论是哪种形式,hello/hello.h 这一头文件, 都会被自己的源代码 test_hello.cpp 包含, 从而参与到 example 工程的构建中。 而 example 工程可能使用了和 hello 不同的 "treat warning as errors" 设定, 会导致 hello.h 在 hello 工程中不会编译报错, 但在 example 工程中就会报错了。
我们的预期是:hello.h 在参与到 example/test_hello.cpp 的预处理过程时, 不要使用 example/CMakeLists.txt 里的严格的编译报错设定, 放宽它的编译报错等级; 同时保持 test_hello.cpp 自身的 cpp 代码, 仍然是被严格处理的。
2.2 头文件 hello.h 内容
2.3 test_hello.cpp 内容
2.4 根目录 CMakeLists.txt 内容
2.5 完整工程
github.com/zchrissirhcz...
3. Linux下的运行结果和分析
3.1 运行结果: 使用 SYSTEM 后, 头文件 hello/hello.h 不再触发编译报错
3.2 检查 compile_commands.json 里的具体编译命令, -I 被 -isystem 替代
3.3 -I 和 -isystem 的区别是什么? man gcc 可以知道, 被 -isystem 指定的目录, 会被当作标准系统目录对待:
而人们提到的
-isystem
会忽略自行在 makefile/CMakeLists.txt 中指定的 warning, 可以在 gcc 在线文档中找到:
3.4include_directories() 和 target_include_directories() 也可以用 SYSTEM 在 How to suppress GCC warnings from library headers? 问答中, 有人提到可以在 include_directories() 中指定 SYSTEM 关键字来抑制编译警告:
查看文档得到验证:
实际上,
target_include_directories()
也可以用
SYSTEM
关键字, 也是生成
-isystem
的编译命令:
查看 compile_commands.json 验证:
4. 使用 -isystem 的进一步探讨
4.1 -Wsystem-headers 开启 system headers 的 warning man gcc 可以知道, 提供的 -Wsystem-headers 编译选项, 是把 system headers 里的警告开启, 也就是说当你用 -isystem 指定了一个三方库路径后, 如果想开启它里面的 warning, 可以用 -I 替代 -isystem 来开启 warning, 也可以用 -Wsystem-headers 来开启 warning:
4.2 使用 -fsystem-headers 的提议 (尚未实现)
在 Bug 93506 - Create hybrid of -I and -isystem that is like -I but deactivates warnings 中有人提到, 人们使用 -isystem /some/path 替代 -I /some/path, 有点滥用系统头文件路径的问题, 考虑让 gcc 增加 -fsystem-headers 参数, 进而使用:
来让/some/path 被搜索时忽略警告。 不过这个 feature 尚未实现。
5. MSVC 下的结果
MSVC 使用/I, 和 GCC 的 -I 对应; MSVC 使用 /externel:W0, 和 GCC 里的 -isystem 对应。
作为实验, 先前-Werror=shadow 的写法, 在 MSVC 下要更换为:
6. 总结
CMake 中, 有如下几个命令, 都可以使用SYSTEM 关键字, 使得被添加的头文件搜索目录中, 头文件里的 warning 完全被编译器忽略:
上述这些 cmake 命令, 是映射-I dir 为 -isystem dir, 根据 GCC 文档, -isystem 指定的 dir 被当作标准系统头文件目录:
由于编译器本身忽略了-isystem 指定目录中的警告, 那么开发者在 CMakeLists.txt 里指定的 treat warnings as errors 的设定, 由于没捕获到这些目录里的 waring, 因而不会触发编译报错。 这是一种避免陷入修改第三方库头文件源码的方法, 它仅对于头文件有效, 对于 add_subdirectories() 引入的源代码文件 (.c/.cpp) 不起作用。
在 GCC 和 MSVC 下,SYSTEM 关键字都起作用。
7. References
本文使用 Zhihu On VSCode 创作并发布
❸ 怎么忽略KEIL的警告
见图片