如何禁用gcc在第三方代码中出现的未使用变量警告,而我不希望编辑这些代码?

130

我想知道在gcc编译器中传递哪个开关可以关闭未使用变量的警告?我在Windows上使用boost时出现了错误,但我不想触碰boost代码:

C:\boost_1_52_0/boost/system/error_code.hpp: At global scope:
C:\boost_1_52_0/boost/system/error_code.hpp:214:36: error: 'boost::system::posix_category' defined but not used [-Werror=unused-variable]
C:\boost_1_52_0/boost/system/error_code.hpp:215:36: error: 'boost::system::errno_ecat' defined but not used [-Werror=unused-variable]
C:\boost_1_52_0/boost/system/error_code.hpp:216:36: error: 'boost::system::native_ecat' defined but not used [-Werror=unused-variable]

我尝试使用 -Wunused-value-Wno-unused-value,但都没有抑制上述消息。

正确的命令是什么,这是我的编译行:

g++  -g -fno-inline -Wall -Werror -Wextra -Wfloat-equal -Wshadow
-Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wno-conversion 
-Wdisabled-optimization -Wredundant-decls -Wunused-value -Wno-deprecated 
-IC:\\boost_1_52_0 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
-c -o op.o op.cpp

也许 -Wall 覆盖了我的目标?

正如错误信息所说,尝试使用“-Werror=no-unused-variable”。 - Joachim Isaksson
可能是如何最好地消除有关未使用变量的警告?的重复问题。 - Jim Fell
我非常确定“未使用的值”和“未使用的变量”是两个不同的概念,否则为什么会有两个不同的选项呢? - n. m.
10个回答

287
-Wno-unused-variable开关通常能解决问题。然而,如果您在项目中关心这些事情,那么这是一个非常有用的警告。但当GCC开始警告您关于代码中不存在的内容时,它会变得很烦人。
我建议您保留警告,但对于第三方项目的包含目录,请使用-isystem而不是-I。该标志告诉GCC不要警告您无法控制的内容。
例如,使用-isystem C:\\boost_1_52_0代替-IC:\\boost_1_52_0

1
把这个设置加在哪里?我放在“项目设置 / AVR GNU C编译器 / 其他”下了,但它会被忽略(路径正确,仍然收到警告)。当将其添加到目录设置中(取消相对路径复选框),AtmelStudio会崩溃。 - hfrmobile
5
我们还有-Wno-unused-parameter用于未使用的函数参数,-Wno-unused-function用于未使用的函数。 - Ngo Thanh Nhan
3
您需要的是:-Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable - Ronny Sherer

109
有时候你只想忽略一些警告,而保留其他警告以确保安全。在你的代码中,可以使用GCC的unused属性来忽略变量甚至形式参数的警告。假设你有以下代码片段:

Sometimes you just need to suppress only some warnings and you want to keep other warnings, just to be safe. In your code, you can suppress the warnings for variables and even formal parameters by using GCC's unused attribute. Lets say you have this code snippet:

void func(unsigned number, const int version)
{
  unsigned tmp;
  std::cout << number << std::endl;
}

有时候,你需要将这个函数作为一个处理器来使用 - 在C++ Boost库中这是相当常见的情况(我认为)。然后你需要第二个形式参数version,以便函数的签名与处理器所需的模板相同,否则编译将失败。但实际上在函数本身中也不一定需要它...

如何标记变量或形式参数以排除警告的解决方案如下:

void func(unsigned number, const int version __attribute__((unused)))
{
  unsigned tmp __attribute__((unused));
  std::cout << number << std::endl;
}

GCC有许多其他参数,您可以在man页面中检查它们。这也适用于C程序,不仅限于C ++,我认为它几乎可以用在任何函数中,而不仅仅是处理程序。去试试吧!;)

P.S .:最近我使用它来抑制像这样的模板中Boosts' serialization的警告:

template <typename Archive>
void serialize(Archive &ar, const unsigned int version __attribute__((unused)))

编辑:显然,我没有按照你的需求回答你的问题,drak0sha做得更好。这是因为我主要遵循了问题的标题,我的错。希望这可能对其他因该标题而来到这里的人有所帮助...:)


9
对于形式参数,您可以省略名称,例如void func(unsigned number, const int)。这样,gcc也不会抱怨未使用的version - Olaf Dietsche
@OlafDietsche 我认为这取决于您使用的 gcc 版本。如果我没记错的话,4年前我不得不使用它来抑制有关未使用的 version 的警告。 ;) - Dee'Kej

92

如果您正在使用gcc并且想要禁用选定代码的警告,则可以使用#pragma编译器指令:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
( your problematic library includes )
#pragma GCC diagnostic pop

对于您控制的代码,您还可以使用__attribute__((unused))来指示编译器特定变量未被使用。


一般来说,我会说使用#pragma指令并不是很安全,除非你真的知道自己在做什么,或者你正在使用例如OpenMP进行并行化... ;) - Dee'Kej
1
@Dee'Kej 如果你把 #pragma 指令放进 #ifdef some_compiler ... #endif 里面,那么它是非常安全的。警告信息是编译器特定的功能,不是由标准定义的。如果没有 #pragma,就不能抑制任何来自代码的警告。 - Kotauskas
@vladislav-toncharov 你说的警告信息与编译器有关,确实正确。但是我们这里不是在谈论普遍意义上的编译器警告,而是在具体讨论 GCC 的情况。你也是正确的,#pragma 本身并不会有害。但是,在我看来,很多人不知道如何正确使用 #pragma,这就是为什么我认为它是“危险”的原因(话虽这么说,但还是欠缺更好的表述方式)。 - Dee'Kej

19
请参考man gcc中的警告选项,其中包括许多unused选项。

警告选项
... -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable

如果在任何一个选项前加上no-,则会禁用该警告。

许多选项的名称以-f或-W开头,例如-fmove-loop-invariants、-Wformat等。大多数选项都有正面和负面形式;-ffoo的负面形式将是-fno-foo。本手册仅记录这两种形式中的一种,即不是默认值的那一种。

更详细的解释可以在Options to Request or Suppress Warnings找到。

不知道我可以在任何警告前加上“no-”。 - RNA

14

使用 -Wno-unused-variable 应该可以解决问题。


啊,是未使用的变量,不是未使用的值! - WilliamKF
7
如果你想移除错误但保留警告,可以使用-Wno-error=unused-variable - Oskar N.
1
你实际上可以看到实际警告是什么 [-Werror=unused-variable] - Mats Petersson

7
您可以在变量前加上“(void)”前缀。如果您无法访问构建框架或仅想影响本地行为的更改,这将非常有用。
例如:
int main()
{
  int unused1;       //This will print warning
  int unused2;       //This will not print warning -
                     //                             |
  (void) unused2;    // <----------------------------
}

输出:

$ g++ -Wall test.cc
test.cc: In function ‘int main()’:
test.cc:4:7: warning: unused variable ‘unused1’ [-Wunused-variable]
    4 |   int unused1;
      |       ^~~~~~~

4

如何禁用gcc发出的未使用变量警告?
我在Windows上使用boost时遇到错误,但我不想修改boost代码...

您可以访问Boost的Trac并对Boost进行错误报告。

您的应用程序不负责清除库中的警告和错误。库本身负责清除其自己的警告和错误。


3
编译器已经告诉你,不是value而是variable。您需要寻找-Wno-unused-variable。此外,请尝试g++ --help=warnings以查看可用选项列表。

0

我建议既不要编辑第三方代码,也不要全局禁止警告。如果您正在使用CMake,则可以仅针对外部库抑制特定警告。

find_package(Boost REQUIRED)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    target_compile_options(Boost::boost PUBLIC -Wno-unused-variable)
endif()
...
add_executable(main "main.cpp")
target_link_libraries(main Boost::boost)

另请参见FindBoost.cmake


0

-Wall-Wextra在GCC中设置了舞台,随后的-Wno-unused-variable可能不会生效。例如,如果您有:

CFLAGS += -std=c99 -pedantic -pedantic-errors -Werror -g0 -Os \ -fno-strict-overflow -fno-strict-aliasing \ -Wall -Wextra \ -pthread \ -Wno-unused-label \ -Wno-unused-function \ -Wno-unused-parameter \ -Wno-unused-variable \ $(INC)

那么GCC看到指令-Wall -Wextra,似乎忽略了-Wno-unused-variable

这可以改为以下形式,从而获得不在编译时停止使用未使用变量的所需效果:

CFLAGS += -std=c99 -pedantic -pedantic-errors -Werror -g0 -Os \ -fno-strict-overflow -fno-strict-aliasing \ -pthread \ -Wno-unused-label \ -Wno-unused-function \ $(INC)

所以将它称为“警告”而不是“错误”是有原因的。因为代码没有完成(比如说你在填充算法)而让编译失败会很沮丧。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接