7

I have a header, core/types.hh, used by several different build targets. It has the following declaration:

core/types.hh

typedef std::size_t  Size;

static const Size SZ_MAX = std::numeric_limits<Size>::max();
...

Some of the targets use this constant, some don't. So I get:

error: 'core::SZ_MAX' defined but not used"

I use scons with GCC 4.7.3 on Linux. I have -Wall set and want to keep it that way.

As far as I understand from the GCC documentation, this shouldn't give a warning:

-Wunused-variable

Warn whenever a local variable or non-constant static variable is unused aside from its declaration. This warning is enabled by -Wall.

So I don't see why I get a warning (which turns into an error).

On other answers, people were advised to make the declaration extern and to do the assignment in the file that uses the constant. This file is used by many other files, so it would loose its constant-ness if I do that. Furthermore, this file has header guards, so I think this should mean that the constant is actually created only once.

I'd appreciate any help!

Yuval


Possible duplicates:

Community
  • 1
  • 1
Yuval
  • 3,207
  • 32
  • 45
  • 2
    Not relevant for the error message, but in the declaration `static const Size SZ_MAX` note that (1) `static` is the default for a constant at namespace scope, and (2) ALL UPPERCASE is by modern convention reserver for macro names, so you can avoid some possible problems by using an ordinary lowercase or mixed case name. – Cheers and hth. - Alf May 29 '14 at 10:38
  • Also, you can avoid some possible problems due to modern C and C++ rules for implicit conversions (plus wrap-around behavior for unsigned types), by defining `Size` as a *signed* type, e.g. `ptrdiff_t`. – Cheers and hth. - Alf May 29 '14 at 10:41
  • Finally, you can avoid some possible problems by including `` instead of ``, and writing `::ptrdiff_t` instead of `std::ptrdiff_t` (or, if doing the Right Thing just feels too unconventional, `::size_t` instead of `std::size_t`). – Cheers and hth. - Alf May 29 '14 at 10:42
  • Regarding the problem of warning/error, it appears to be due to a bug, either in functionality or documentation. Anyway a possible fix is to make the compiler believe that the constant is used. I would first check whether a `static_assert` is enough. If not, then a dummy cpp file might be necessary (it's a good idea anyway in order to check that headers are self-reliant). – Cheers and hth. - Alf May 29 '14 at 10:45
  • 1
    Oh, regarding the name, do note that Microsoft uses the prefix "sz" to indicate a *zero-terminated string*. Thus people maintaining code that uses your constant can easily misunderstand it. Generally there's no point in writing e.g. `hlt` instead `halt`, `mov` instead of `move`, and so. They're just counter-productive silly shortenings. So, write `size_max`, not `sz_max`. Or better, introduce a less verbose name for `std::numeric_limits`, which can be done via a C++11 `using`. – Cheers and hth. - Alf May 29 '14 at 10:49
  • 1
    I can't manage get a warning for this, and I've tested the latest release of all minor versions back to 4.1. Are you sure the code isn't doing something silly like `#define const /*non-const*/`? Are you perhaps not mentioning some relevant compiler flags needed to produce the warning? –  May 29 '14 at 10:59
  • 2
    I'm also unable to reproduce, using MinGW g++ 4.8.2 with command line `g++ foo.cpp -Wunused-variable -O2 -pedantic -std=c++11`. @hvd: note that optimization, e.g. just `-O`, is necessary to engage or unleash the g++ used/unused detector to the full. – Cheers and hth. - Alf May 29 '14 at 11:02

1 Answers1

3

It seems that this was not the error that halted compilation.

Rather, if GCC find another error, it would still report on this too.

I actually had another unused variable, and that's what caused this error in the first place.

For example, when creating the following files:

file1.cc

#include "head1.hh"

int main() {
    int bad_unused_variable;
    return my_ns::JUST_ANOTHER_CONST;
}

head1.hh

#ifndef HEAD1
#define HEAD1

#include <stdint.h>
#include <cstddef>
#include <limits>

namespace my_ns {
    typedef std::size_t Size;
    static const Size SZ_MAX = std::numeric_limits<Size>::max();
    static const Size JUST_ANOTHER_CONST = 8;
}

#endif

You get:

> g++ -Wall -Werror file1.cc -O2 -std=c++98 -o file1
file1.cc: In function 'int main()':
file1.cc:4:6: error: unused variable 'bad_unused_variable' [-Werror=unused-variable]
In file included from file1.cc:1:0:
head1.hh: At global scope:
head1.hh:10:20: error: 'my_ns::SZ_MAX' defined but not used [-Werror=unused-variable]
cc1plus: all warnings being treated as errors

EDIT This also seems to have been answered here: gcc warnings: defined but not used vs unused variable - there they mention the subtle differences between the two warning messages (unused variable vs defined but not used). Still, it doesn't really answer as to why GCC behaves this way...

Community
  • 1
  • 1
Yuval
  • 3,207
  • 32
  • 45
  • I think GCC opts to print suppressed warnings (or at least these ones) if there is an error, as a help to debugging the real problem. As long as there's no error, they will remain suppressed. I assume it's intentional, but in practice can be confusing! – andybuckley Nov 05 '15 at 11:17