Какой стандартный заголовок С++ определяет SIZE_MAX?
Я работаю над существующей кодовой базой С++, которая используется в 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
, используемой в разных местах, прежде чем внести некоторые изменения. Изменения, которые я сделал, заставили его стать undefined в одном исходном файле .cpp
, где он был использован (остальные продолжают быть прекрасными). Таким образом, в моей системе есть некоторый заголовочный файл, где он правильно определен.
Ответы
Ответ 1
Вероятно, что заголовок был определен __STDC_LIMIT_MACROS
и __STDC_CONSTANT_MACROS
до stdint.h
.
Компиляция в Linux с помощью g++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp
должна устранить эту проблему для старых компиляторов.
Если вы хотите узнать больше об этих макросах...
Ответ 2
18.4.1 Контекст заголовка <cstdint>
Заголовок также определяет многочисленные макросы формы:
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
ИЗМЕНИТЬ
В текущем стандарте С++ 11/14, SIZE_MAX
вводится и упоминается только в <cstdint>
. Он также является частью C99
, спецификация С++ 11 полностью включает в себя заголовки <cxxx>
. Таким образом, кажется, что он не был определен до С++ 11.
Ответ 3
Какой стандартный заголовок С++ определяет 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()
не, константа времени компиляции является еще одной загадкой С++, но это другая проблема).