Какой стандартный заголовок C++ определяет SIZE_MAX?

Я работаю над существующей кодовой базой C++, которая использует SIZE_MAX в нескольких местах. Я сделал некоторый рефакторинг и сейчас SIZE_MAX не определен ни в одном из модулей. Эта проблема появилась, когда Travis-CI попытался построить проект на Linux. Он хорошо работал, прежде чем я рефакторинг вещи, но отследить, какие именно заголовочные файлы были включены, сложно.

В попытке воспроизвести проблему локально, я установил виртуальную машину Ubuntu с gcc по умолчанию и смог воспроизвести ее. Вот соответствующий источник:

#include <stddef.h>

int main()
{
    size_t a = SIZE_MAX;
}

Командная строка просто:

g++ a.cpp

Ошибка:

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

Системная информация:

$ 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

Я пытался в том числе cstdint, stdint.h, limits.h, inttypes.h, stdio.h, stdlib.h и, возможно, некоторые другие, и я не могу понять, какой конкретный заголовочный файл мне нужен для SIZE_MAX,

Важно отметить, что программа, над которой я работаю, скомпилирована нормально, с SIZE_MAX используется в разных местах, прежде чем я сделал некоторые изменения. Изменения, которые я сделал, привели к тому, что он стал неопределенным в одном .cpp исходный файл, где он использовался (остальные по-прежнему в порядке). Таким образом, в моей системе существует заголовочный файл, в котором он правильно определен.

3 ответа

Решение

Вполне вероятно, что некоторые заголовки определены __STDC_LIMIT_MACROS а также __STDC_CONSTANT_MACROS до stdint.h был включен.

Компиляция на Linux с g++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp следует исправить эту проблему на старых компиляторах.

Если вы хотите узнать больше об этих макросах...

18.4.1 Заголовок синопсис

Заголовок также определяет многочисленные макросы вида:

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

РЕДАКТИРОВАТЬ

В текущем стандарте C++11/14, SIZE_MAX вводится и упоминается только в <cstdint>, Это также часть C99из которых спецификация C++ 11 полностью включает в себя <cxxx> заголовки. Так что, похоже, он не был определен до C++ 11.

Какой стандартный заголовок C++ определяет SIZE_MAX?

Это должно быть определено в <cstdint>, но это необязательно.

Вот результаты на Fedora 22 с GCC 5.1:

#include <cstdint>

// use SIZE_MAX

Результаты в:

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
                                    ^

Проще было сделать следующее и перестать беспокоиться о непереносимой необязательности, которая все еще вызывает проблемы в 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

Попытка __SIZE_MAX__ возвращает вас к постоянной времени компиляции, которую вы, вероятно, жаждете. Вы можете увидеть, определено ли оно в препроцессоре с cpp -dM < /dev/null | grep __SIZE_MAX__,

(И как / почему numeric_limits<size_t>::max() не является постоянной времени компиляции, это еще одна загадка C++, но это другая проблема).

Другие вопросы по тегам