19

I'm working on an existing C++ codebase that happens to use SIZE_MAX in a couple of places. I did some refactoring and now SIZE_MAX is not defined in one of the modules. This problem appeared when Travis-CI attempted to build the project on Linux. It worked fine before I refactored stuff, but tracing which exact header files were included is difficult.

In an attempt to replicate the problem locally, I installed an Ubuntu VM with the default gcc and was able to reproduce it. Here's the relevant source:

#include <stddef.h>

int main()
{
    size_t a = SIZE_MAX;
}

The command line is simply:

g++ a.cpp

The error is:

a.cpp: In function ‘int main()’:
a.cpp:5:16: error: ‘SIZE_MAX’ was not declared in this scope

System info:

$ uname -a
Linux quartz 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

I have tried including cstdint, stdint.h, limits.h, inttypes.h, stdio.h, stdlib.h, and probably some others, and I can't figure out which specific header file I need for SIZE_MAX.

It is important to note that the program I'm working on compiled fine, with SIZE_MAX used in various places, before I made some changes. The changes I made caused it to become undefined in one .cpp source file where it was used (the others continue to be fine). So there exists some header file on my system where it is correctly defined.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 1
    Have you tried `cstdint` ... section *[cstdint.syn]* says it should be there but it should also be in `stdint.h`. – Shafik Yaghmour May 27 '15 at 03:40
  • 1
    @ShafikYaghmour: I have, and the compiler warns me that including that header requires the `-std=c++0x` switch, but this isn't a C++11 program and I don't want to change that. It still fails to find `SIZE_MAX` when including `cstdint` anyway. – Greg Hewgill May 27 '15 at 03:42
  • Take a look on this https://groups.google.com/forum/#!msg/snap-discuss/giu_IMZndxI/CYP98BGvf7QJ – Santhucool May 27 '15 at 03:43
  • 1
    @iammilind: I have read that question. It's not a duplicate. That question is understanding what `SIZE_MAX` means, while my question relates to which header file I need to include to get it. – Greg Hewgill May 27 '15 at 03:45
  • @Santhucool: That's interesting, but seems specific to a software package called SNAP that I'm not familiar with and it's unclear how I could fix my program. – Greg Hewgill May 27 '15 at 03:46

3 Answers3

17

It's likely that some header defined __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS before stdint.h was included.

Compiling on Linux with g++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp should fix this issue on the older compilers.

If you'd like to learn more about these macros...

Community
  • 1
  • 1
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
10

18.4.1 Header <cstdint> synopsis

The header also defines numerous macros of the form:

INT_[FAST LEAST]{8 16 32 64}_MIN

[U]INT_[FAST LEAST]{8 16 32 64}_MAX

INT{MAX PTR}_MIN

[U]INT{MAX PTR}_MAX

{PTRDIFF SIG_ATOMIC WCHAR WINT}{_MAX _MIN}

SIZE_MAX

EDIT

In the current C++11/14 standard, SIZE_MAX is introduced and mentioned only in <cstdint>. It is also part of C99, of which specification C++11 fully includes via the <cxxx> headers. So it seems it was not defined prior to C++11.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 2
    @GregHewgill unfortunately I don't have a copy of the C++98/03 standard. I am not even sure it was defined before. I think it is defined by the C99 standard, and afaik, C++11 fully includes C99 specifications. – vsoftco May 27 '15 at 03:46
  • @vsoftco: C++ 2003 did not include `cstdint` and therefore did not include `SIZE_MAX`. – Bill Lynch May 27 '15 at 03:46
  • 1
    @BillLynch yes that's what I was basically saying, that it seems to be newly introduced in C++11 (although it was part of C99 before). – vsoftco May 27 '15 at 03:48
  • C++03 did not use C99 as a normative reference. – Shafik Yaghmour May 27 '15 at 03:49
  • @ShafikYaghmour thanks, I edited the answer, I knew also that C++11 was the first version that fully incorporated C99. – vsoftco May 27 '15 at 03:51
  • @vsoftco No, no C++-Standard do fully incorporated C-Standards. For example, C99 have `restrict` which C++ do not have. Also there are many things which are different in C than in C++ (type of a character literal, keyword `const`, ...) – 12431234123412341234123 Aug 22 '17 at 11:39
  • @12431234123412341234123 I meant that C++11 falls back fully on C99 in terms of normative references. Surely it doesn't include the C99 standard. – vsoftco Oct 03 '17 at 08:57
3

Which C++ standard header defines SIZE_MAX?

Its supposed to be defined in <cstdint>, but its optional.

Here are the results on Fedora 22 with GCC 5.1:

#include <cstdint>

// use SIZE_MAX

Results in:

g++ -DNDEBUG -g -O2 -fPIC -march=native -pipe -c filters.cpp
In file included from /usr/include/c++/5.1.1/cstdint:35:0,
                 from filters.cpp:14:
/usr/include/c++/5.1.1/bits/c++0x_warning.h:32:2: error: #error This file requires  
compiler and library support for the ISO C++ 2011 standard. This support is currently
experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
 #error This file requires compiler and library support for the \
  ^
filters.cpp: In constructor ‘Filter::Filter(BufferedTransformation*)’:
filters.cpp:305:36: error: ‘SIZE_MAX’ was not declared in this scope
  : Filter(attachment), m_firstSize(SIZE_MAX), m_blockSize(0), m_lastSize(SIZE_M
                                    ^

It was simply easier to do the following, and stop worrying about non-portable optional-ness that still causes problems in 2015.

#include <limits>

#ifndef SIZE_MAX
# ifdef __SIZE_MAX__
#  define SIZE_MAX __SIZE_MAX__
# else
#  define SIZE_MAX std::numeric_limits<size_t>::max()
# endif
#endif

Trying __SIZE_MAX__ gets you back to the compile time constant that you probably crave. You can see if its defined in the preprocessor with cpp -dM < /dev/null | grep __SIZE_MAX__.

(And how/why numeric_limits<size_t>::max() is not a compile time constant is another C++ mystery, but that's a different problem).

jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    "`numeric_limits::max()` is not a compile time constant" - with which standard? http://en.cppreference.com/w/cpp/types/numeric_limits/max says it is constexpr since C++11 (thanks for hint to user 1913600 - romain-b). – osgx Aug 01 '17 at 23:36
  • The alternative definition is `#define SIZE_MAX (static_cast(-1))` rather than using `numeric_limits`. – Martin Bonner supports Monica Dec 13 '18 at 09:22