19

我正在研究一个恰好SIZE_MAX在几个地方使用的现有 C++ 代码库。我做了一些重构,现在SIZE_MAX没有在其中一个模块中定义。当Travis-CI试图在 Linux 上构建项目时,就会出现这个问题。在我重构之前它工作得很好,但是很难跟踪包含了哪些确切的头文件。

为了在本地复制问题,我安装了一个带有默认 gcc 的 Ubuntu VM,并且能够重现它。以下是相关来源:

#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源文件中变得未定义(其他的仍然很好)。所以在我的系统上存在一些正确定义的头文件。

4

3 回答 3

17

很可能包含了一些之前定义__STDC_LIMIT_MACROS的标头。__STDC_CONSTANT_MACROSstdint.h

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

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

于 2015-05-27T03:54:50.583 回答
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 之前没有定义。

于 2015-05-27T03:41:47.490 回答
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++ 之谜,但这是一个不同的问题)。

于 2015-09-02T02:57:44.800 回答