g++-5.1.1 warns about unused variable only when op

2020-06-16 04:44发布

问题:

In a large project, I've been getting some compiler warnings from g++-5.1.1 only when building the release version (which uses optimization flags) but not while building the debug version (which disables most compiler optimization). I've narrowed down the problem to a minimal example listed below with commands to reproduce the problem. The problem does not occur if I use g++-4.8.4. Is this a bug in g++-5.1.1? Or, is this code doing something that is legitimately wrong and warrants that warning? Why doesn't it produce any warnings for the last three cases listed in the code (see edit at the bottom for some explanation)?

For those who are interested, here is the bug report in GCC's Bugzilla.

/*

This code complains that the variable 'container' is unused only if optimization
flag is used with g++-5.1.1 while g++-4.8.4 does not produce any warnings in
either case.  Here are the commands to try it out:

$ g++ --version
g++ (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -c -std=c++11 -Wall  -g -O0 test_warnings.cpp

$ g++ -c -std=c++11 -Wall  -O3 test_warnings.cpp
test_warnings.cpp:34:27: warning: ‘container’ defined but not used [-Wunused-variable]
 const std::array<Item, 5> container {} ;
                            ^
*/
#include <array>
struct Item 
{
    int itemValue_ {0} ;
    Item() {} ;
} ;

//
// The warning will go away if you do any one of the following:
// 
// - Comment out the constructor for Item.
// - Remove 'const' from the next line (i.e. make container non-const).
// - Remove '{}' from the next line (i.e. remove initializer list).
//
const std::array<Item, 5> container {} ;
//
// These lines do not produce any warnings:
//
const std::array<Item, 5> container_1 ;
std::array<Item, 5> container_2 ;
std::array<Item, 5> container_3 {} ;

Edit: As mentioned by Ryan Haining in the comments, container_2 and container_3 will have extern linkage and the compiler has no way of warning about their usage.

回答1:

This looks like a bug, if we look at the documentation for -Wunused-variable it says (emphasis mine):

This option implies -Wunused-const-variable for C, but not for C++

and if we look at -Wunused-const-variable it says:

Warn whenever a constant static variable is unused aside from its declaration. This warning is enabled by -Wunused-variable for C, but not for C++. In C++ this is normally not an error since const variables take the place of #defines in C++.

and we can see this warning goes away in the head revision of gcc.

This gcc bug report: -Wunused-variable ignores unused const initialised variables is also relevant. Although it is against C the C++ case is also discussed.