在GCC版本高于4.4的环境中,如何忽略未知的警告选项?

编程语言 2026-07-09

据称 这是足够旧的gcc版本的默认行为

不幸的是,gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0(并且据 另一条注释 所述,已经是gcc 7.3.0)已经回退并默认发出警告,而 -Werror 将其正式提升为错误。

我的程序在较新的gcc下构建没问题;如果我移除选项 -Wbidi-chars=any,在gcc 11也能编译通过。

启用该选项后,gcc 11会报错:

c++: error: unrecognized command-line option ‘-Wbidi-chars=any’

如何抑制这个被提升为错误的特定警告?

推测如果它已经作为默认行为实现过,那么这个能力并不是简单地从gcc中移除。

(我也想添加其他gcc警告,这些警告在我当前可用的任何gcc版本中尚未得到支持,作为未来的准备工作,例如升级到 -Wbidi-chars=any,ucn,让较旧的gcc将此视为它们所熟知的 -Wbidi-chars=any。)

但这更像是一个扩展目标,因为我已经把所有这些记在一个清单中,准备在项目的主gcc版本提升时再处理。

我最担心的是避免对较旧的gcc版本作出妥协,例如在CMakeLists.txt中对编译器版本加上条件。

我的完整选项列表:

add_compile_options(
    -finput-charset=UTF-8 # TODO https://gitlab.kitware.com/cmake/cmake/-/work_items/23530 replace with CMAKE built-in!
#  enabled warnings
    -Wall
    -Walloc-zero
    -Walloca
    -Warith-conversion
    -Warray-bounds=2
    -Wattribute-alias=2
    -Wbidi-chars=any
    -Wcast-align
    -Wcast-qual
    -Wconversion
    -Wdate-time
    -Wdisabled-optimization
    -Wdouble-promotion
    -Wduplicated-branches
    -Wduplicated-cond
    -Werror
    -Wextra
    -Wfloat-conversion
    -Wfloat-equal
    -Wformat-overflow=2
    -Wformat-signedness
    -Wformat-truncation=2
    -Wformat-y2k
    -Winline
    -Winvalid-pch
    -Wlogical-op
    -Wmissing-include-dirs
    -Wnormalized=nfkc
    -Wopenmp-simd
    -Wpacked
    -Wpedantic
    -Wredundant-decls
    -Wshadow
    -Wshift-overflow=2
    -Wsign-conversion
    -Wstrict-overflow=5
    -Wstringop-overflow=4
    -Wsuggest-attribute=noreturn
    -Wsync-nand
    -Wtrampolines
    -Wundef
    -Wuninitialized
    -Wunsafe-loop-optimizations
    -Wunused-const-variable=2
    -Wunused-macros
    -Wuseless-cast
    -Wvector-operation-performance
    -Wvla
    -Wzero-as-null-pointer-constant
# disabled warnings
    -Wno-parentheses
)

解决方案

按惯例,它可以像下面这样实现,不对编译器版本设条件。

include(CheckCompilerFlag)

add_compile_options(
    -finput-charset=UTF-8 # TODO https://gitlab.kitware.com/cmake/cmake/-/work_items/23530 replace with CMAKE built-in!
#  enabled warnings
    -Wall
    -Walloc-zero
    -Walloca
    -Warith-conversion
    -Warray-bounds=2
    -Wattribute-alias=2
    -Wcast-align
    -Wcast-qual
    -Wconversion
    -Wdate-time
    -Wdisabled-optimization
    -Wdouble-promotion
    -Wduplicated-branches
    -Wduplicated-cond
    -Werror
    -Wextra
    -Wfloat-conversion
    -Wfloat-equal
    -Wformat-overflow=2
    -Wformat-signedness
    -Wformat-truncation=2
    -Wformat-y2k
    -Winline
    -Winvalid-pch
    -Wlogical-op
    -Wmissing-include-dirs
    -Wnormalized=nfkc
    -Wopenmp-simd
    -Wpacked
    -Wpedantic
    -Wredundant-decls
    -Wshadow
    -Wshift-overflow=2
    -Wsign-conversion
    -Wstrict-overflow=5
    -Wstringop-overflow=4
    -Wsuggest-attribute=noreturn
    -Wsync-nand
    -Wtrampolines
    -Wundef
    -Wuninitialized
    -Wunsafe-loop-optimizations
    -Wunused-const-variable=2
    -Wunused-macros
    -Wuseless-cast
    -Wvector-operation-performance
    -Wvla
    -Wzero-as-null-pointer-constant
# disabled warnings
    -Wno-parentheses
)

check_compiler_flag(CXX -Wbidi-chars=any _have_bidi_chars)
if(_have_bidi_chars)
    add_compile_options(-Wbidi-chars=any)
endif()

更多信息,请参见 CheckCompilerFlag,这很简单。

一个辅助函数可以像下面这样:

# file: functions.cmake
include(CheckCompilerFlag)

function(add_compile_options_that_exist)
    foreach(opt IN LISTS ARGN)
        string(MAKE_C_IDENTIFIER "HAS_OPT_${opt}" opt_var)
        check_compiler_flag(CXX "${opt}" ${opt_var})
        if(${opt_var})
            add_compile_options("${opt}")
        endif()
    endforeach()
endfunction()

用法:

# other CMakeLists.txt
include(functions.cmake)

# add all the mandatory options:
add_compile_options(...)

# add all the optional options:
add_compile_options_that_exist(-Wbidi-chars=any)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章