哪个C++标准头文件定义了SIZE_MAX?

19

我正在处理一个现有的C++代码库,它在几个地方使用了SIZE_MAX。我进行了一些重构,现在其中一个模块中未定义SIZE_MAX。当Travis-CI尝试在Linux上构建项目时出现了问题。在我重构之前,它正常工作,但是跟踪包含哪些确切头文件很困难。

为了在本地复制该问题,我安装了一个带有默认gcc的Ubuntu虚拟机,并成功复制了该问题。以下是相关源代码:

#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

我尝试了包括 cstdintstdint.hlimits.hinttypes.hstdio.hstdlib.h,以及可能还有其他的头文件,但我无法找出我需要哪个特定的头文件来获取 SIZE_MAX

需要注意的是,在我做一些更改之前,我正在处理的程序编译得很好,并在各个地方使用了 SIZE_MAX。我所做的更改导致它在一个被使用的 .cpp 源文件中变成了未定义的(其他源文件仍然正常)。因此,在我的系统上存在某些正确定义它的头文件。


1
你尝试过使用 cstdint 吗?在 [cstdint.syn] 部分中说它应该在那里,但它也应该在 stdint.h 中。 - Shafik Yaghmour
1
@ShafikYaghmour:我试过了,编译器警告我包含那个头文件需要使用“-std=c++0x”开关,但这不是一个C++11程序,我不想改变它。即便如此,在包括“cstdint”时仍然无法找到“SIZE_MAX”。 - Greg Hewgill
请查看此链接 https://groups.google.com/forum/#!msg/snap-discuss/giu_IMZndxI/CYP98BGvf7QJ - Santhucool
1
@iammilind:我已经阅读了那个问题。它不是重复的。那个问题是理解SIZE_MAX的含义,而我的问题是关于我需要包含哪个头文件才能获得它。 - Greg Hewgill
@Santhucool:很有趣,但似乎只适用于一个叫做SNAP的软件包,我不熟悉它,也不清楚如何修复我的程序。 - Greg Hewgill
3个回答

17

很可能在包含 stdint.h 之前定义了 __STDC_LIMIT_MACROS__STDC_CONSTANT_MACROS 的一些标头。

在 Linux 上使用 g++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp 编译应该可以解决旧编译器的问题。

如果你想了解更多有关这些宏的信息...


10

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

编辑

在当前的 C++11/14 标准中,SIZE_MAX 只在 <cstdint> 中被引入和提到。它也是 C99 的一部分,C++11 通过 <cxxx> 头文件完全包含了其规范。所以它似乎在 C++11 之前没有被定义。


2
很遗憾,@GregHewgill,我没有C++98/03标准的副本。我甚至不确定它是否在此之前被定义过。我认为它是由C99标准定义的,并且据我所知,C++11完全包含了C99规范。 - vsoftco
@vsoftco:C++ 2003 没有包括 cstdint,因此也没有包括 SIZE_MAX - Bill Lynch
1
@BillLynch 是的,这就是我基本上想说的,它似乎是在C++11中新引入的(尽管它之前是C99的一部分)。 - vsoftco
C++03没有将C99作为规范参考。 - Shafik Yaghmour
@ShafikYaghmour 感谢,我已经编辑了答案,我也知道C++11是第一个完全纳入C99的版本。 - vsoftco
显示剩余2条评论

3

哪个C++标准头文件定义了SIZE_MAX?

它应该在<cstdint>中定义,但是这是可选的。

以下是在GCC 5.1上运行Fedora 22的结果:

#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++ 的谜团,但那是另一个问题了)。


2
"numeric_limits<size_t>::max()不是编译时常量" - 适用于哪个标准?http://en.cppreference.com/w/cpp/types/numeric_limits/max 表明自C++11起它是constexpr(感谢用户1913600 - romain-b的提示)。 - osgx
另一种定义是使用#define SIZE_MAX (static_cast<size_t>(-1))而不是使用numeric_limits - Martin Bonner supports Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接