怎麼讓編譯器忽略警告
❶ 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的警告
見圖片