いくつかの場所でたまたまSIZE_MAX
を使用している既存のC++コードベースに取り組んでいます。いくつかのリファクタリングを行いましたが、SIZE_MAX
はモジュールの1つで定義されていません。この問題は Travis-CI がLinuxでプロジェクトをビルドしようとしたときに発生しました。何かをリファクタリングする前は問題なく動作しましたが、含まれている正確なヘッダーファイルを追跡することは困難です。
問題をローカルで再現するために、Ubuntu VM=をデフォルトの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
を使用して問題なくコンパイルされていることに注意してください。 one.cpp
ソースファイルでそれが未定義になるように変更を加えました(他のファイルは引き続き問題ありません)。したがって、システムにsomeヘッダーファイルが正しく定義されて存在します。
__STDC_LIMIT_MACROS
が含まれる前に、__STDC_CONSTANT_MACROS
およびstdint.h
が定義されたヘッダーが含まれている可能性があります。
Linuxでg++ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS a.cpp
を使用してコンパイルすると、古いコンパイラでこの問題が修正されます。
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より前のバージョンでは定義されていなかったようです。
どの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()
はnotコンパイル時定数は別のC++の謎ですが、それは別の問題)。