固定幅整数が定義されているかどうかを確認する方法


25

C ++では、固定幅の整数はオプションとして定義されていますが、実際に定義されているかどうかを確認するための推奨方法を見つけることができないようです。

固定幅の整数が使用可能かどうかを確認するための移植可能な方法は何でしょうか?


機能テストマクロはないようですが、できると思います#if defined(INT8_MIN)
Zereges

2
stdライブラリがそのための機能テストマクロを提供していない場合は、使用するツールチェーンがその機能を提供しているかどうか、または独自のテストを定義できるかどうかを確認できます。たとえば、CMakeを使用すると、定義されたcppファイルをコンパイルし、コンパイルが失敗したかどうかに応じて、定義可能なマクロが設定されているかどうかに応じて、特定の言語機能をテストできます。
t.niese

cmakeよりautoconfを好む場合は、あらかじめ定義されたテストがあります。AC_TYPE_INT8_Tなど
ショーン

stdintにタグスコアがある場合は、IMO cstdintを同義語として指定する必要があります(stackoverflow.com/tags/stdint/synonyms)。このあいまいなことをするために、CとC ++のタグを別々にする必要はないと思います。質問のメインタグで十分です。
Peter Cordes

1
@PeterCordes今回はうまくいきました: stackoverflow.com/tags/stdint/synonyms
Andrew Henle

回答:


16

固定幅整数型が提供されているかどうかを判断するには、対応するマクロ[U]INT*_MAXまたは[U]INT*_MINマクロのいずれかが定義されているかどうかを確認できます。

// may be necessary for your C++ implementation
#define __STDC_LIMIT_MACROS 
#include <cstdint>

#ifdef INT32_MAX
// int32_t must be available to get here
int32_t some32bitIntVariable;
#endif

あたり7.20整数型<stdint.h>、C11標準の段落4(太字の部分を注意してください):

実装が提供する、ここで説明するタイプごとに、<stdint.h>そのtypedef名前を宣言し、関連するマクロ定義します。逆に、実装で提供されていない、ここで説明するタイプごとに、<stdint.h>そのtypedef名前を宣言したり、関連するマクロを定義したりしないでください

C ++はを介してC実装を継承し<cstdint>ます。詳細については、<cstdint>vs<stdint.h>を参照してください。参照してください__STDC_LIMIT_MACROS__STDC_CONSTANT_MACROS意味ですか?詳細については__STDC_LIMIT_MACROS

したがって、場合にはint32_t利用可能で、INT32_MAXかつINT32_MINなければなりません#defineD」。逆に、場合はint32_t利用できません、どちらINT32_MAXINT32_MINあることが許可されている#defineD」。

ただし、@ NicolBolasが別の回答述べたように、実際に確認する必要がない場合もあります。


[U]INT*_C最小および最大マクロの代わりに確認する方が短くなります
phuclv

1
@phuclv同じことを除いて。たとえば、利用可能な場合ではなく、利用可能なINT64_C場合に定義されます。ドキュメントを参照int64_least_tint64_t
オービット

19

大まかに言えば...そうではありません。

固定サイズの整数型を使用する必要がある場合、それそれらの型を特定のサイズにすることを明示的に必要とすることを意味します。つまり、これらのサイズの整数を取得できない場合、コードは機能しなくなります。したがって、それらを使用する必要があります。上記の型がないコンパイラでコードを使用すると、コードはコンパイルされません。コンパイルしてもコードが機能しなかったので、これは問題ありません。

実際に固定サイズの整数は必要ないが、他の理由で単にそれらが必要な場合は、int_least_*型を使用してください。実装がそのサイズを正確に提供できる場合、least_*型はそのサイズになります。


4
これは真実ではありません。以前にuint8_tをサポートしていないプラットフォーム用にoperator = /などを実装するスタブパススルーを作成しました。ただし、効率とデバッグの目的で、実際に必要でない限り、パススルーを使用しないでください。
TLW

@TLW:「私は以前にuint8_tをサポートしていないプラットフォーム用にoperator = /などを実装するスタブパススルーを記述しました。」OK、しかし...なぜですか?あなたが書いたコードは、バイトが8ビットであることを確認する必要があります(これはおそらくを使用していた理由ですuint8_t)が、このコードは、バイトが8ビットではないプラットフォームで実行する必要がありました(これは、古いC ++実装、uint8_tそれが利用できない唯一の理由でしょうか?)つまり、下位互換性の外で、なぜこれを行う必要があったのですか?
ニコルボーラス

プロプライエタリなので、言い過ぎではありません。とりわけ奇抜なハードウェアスタックをサポートする必要がある共有コードベース。以前のアドホック(そしてしばしば壊れている)アプローチよりもはるかに明確uint8_tでした。
TLW

たとえば8ビットバイトで表現されるアルゴリズムを使用している場合、パススルーは1回で作成でき、テストが簡単です。すべての場所を修正するのはその場しのぎであり、微妙に不正確になるのは簡単です。O(1)O(n)努力。人々が例を使用するのと同じ理由uint16_t。あなたは「なぜuint32_tを使用して自分でキャストしないのか」と尋ねていますが、その答えは明白です。
TLW

@TLW:「人々は例えばuint16_tを使用する理由と同じ理由。」ではありません、私の使用する理由uint16_t。私の理由は、私のマシンのエンディアンを使用して、バイナリの符号なし整数としてフォーマットされた正確に16ビットのデータを取得することを期待しているデバイス/フォーマット/などと通信していることです。正確に言えば、それと効果的に通信することははるかに困難です。私のプログラム(および私が使用するAPI)は、それを提供していないマシンでは基本的に機能しません。
Nicol Bolas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.