web-dev-qa-db-ja.com

<cstdint> vs <stdint.h>

stdint.hcstdintの違いは何ですか?

どちらもMSVC(Visual Studio 2010)およびgcc-4.5.1で使用できます。また、両方ともintX_t/uintX_t型を定義します(ここで、Xは型のバイト単位のサイズです)。

  • 両方のヘッダーの理論的根拠が同じ場合(ポータブル型)、どちらを決定するためにどの決定を行う必要がありますか?

stdint.hは名前空間なしで各型を定義し、cstdint型はstd名前空間にあります。

  • 定義された型をstd名前空間に含める、または含めない理由はありますか? 2つのヘッダーの違いは何ですか?

cstdintにはファイル拡張子がなく、cプレフィックスを使用し、stdint.h.h拡張子を使用します。

  • このヘッダーの命名規則は何ですか? cプレフィックスは、これがCライブラリであることを示しますか? cstdintにファイル拡張子がない理由がありますか?
77
PaperBirdMaster

C++ 98の当初の意図は、グローバル名前空間の汚染を避けるために、C++で<cstdint>を使用することでした(特に<cstdint>ではなく、C++ 11でのみ追加されますが、 <c*>ヘッダー全般)。

ただし、とにかくグローバルネームスペースにシンボルを配置することは実装で維持され、C++ 11はこの慣行を承認しました[*]。したがって、基本的に3つのオプションがあります。

  • <cstdint>を使用し、使用する各整数型を完全に修飾するか、using std::int32_t;などでスコープに追加します(冗長なので煩わしいですが、C++の他のシンボルと同じように行うのが正しい方法です)標準ライブラリ)
  • <stdint.h>を使用します(廃止予定のため少し悪いです)
  • <cstdint>を使用し、実装がシンボルをグローバル名前空間に置くと仮定します(保証されていないため非常に悪いです)。

実際には、<cstdint>がシンボルをグローバルネームスペースに配置する実装で偶然に簡単に実行できるため、迷惑な大量のコードが最後のオプションを使用していると思われます。最初のものを使用してみてください。 2番目の方法には1つの長所があります。それはguaranteedであり、多分それを行うのではなく、グローバルな名前空間に置くことです。私はそれが特に役立つとは思いませんが、それがあなたの優先事項であるならば、それはいくらかの入力を節約するかもしれません。

4番目のオプション、#include <cstdint>に続いてusing namespace std;がありますが、これは便利な場合がありますが、using namespace std;を配置しない場所があります。それらの場所は人によって異なりますが、「ヘッダーファイルのトップレベル」は「cppファイルのトップレベル」よりも悪く、「スコープ内」よりも悪いです。 using namespace std;をまったく書かない人もいます。

[*]つまり、C++標準ヘッダーは、グローバルネームスペースにデータを入れることが許可されていますが、必須ではありません。したがって、これらのシンボルとの衝突を避ける必要がありますが、実際には使用できないので、それらが存在しない可能性があります。基本的に、C++のグローバル名前空間は地雷原であり、避けてください。委員会は、ヘッダーファイルのトップレベルにusing namespace std;を貼り付けるのと同じくらい有害な実装による慣行を承認したと主張するかもしれません。違いは、実装がC標準ライブラリのシンボルに対してのみ行うことです。一方、using namespace std;はC++のみのシンボルに対してもそれを行います。 C標準には、標準への将来の追加のために予約されている名前をリストするセクションがあります。これらの名前をC++グローバル名前空間でも予約済みとして扱うことは完全に愚かな考えではありませんが、必須ではありません。

105
Steve Jessop

cstdintを含めると、シンボル名がstd名前空間にインポートされ、可能であればグローバル名前空間にインポートされます。
Include stdint.hは、グローバル名前空間にシンボル名をインポートし、std名前空間に可能性としてインポートします。

C標準ライブラリの機能はC++標準ライブラリでも提供され、一般的な命名規則として、C標準ライブラリの対応する名前の前にcが付加されます。

C++では、次を使用する必要があります。

#include <cstdint>

std::で使用するシンボル名を完全に修飾します
Cの場合、以下を使用する必要があります。

#include <stdint.h>

付録D(規定)互換性機能[depr]状態:

D.6 C標準ライブラリヘッダー

1 C標準ライブラリおよびC Unicode TRとの互換性のために、C++標準ライブラリは、表151に示すように25個のCヘッダーを提供します。

これは含まれて:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h><complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h><ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h><errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h><fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

そしてさらに、

2name.hという形式の名前を持つすべてのCヘッダーは、対応するcname headerによって標準ライブラリの名前空間に配置された各名前がグローバル名前空間スコープこれらの名前が名前空間stdの名前空間スコープ(3.3.6)内で最初に宣言または定義され、その後明示的なusing宣言(7.3.3 )。

3 [例:ヘッダー<cstdlib>は、名前空間std内の宣言と定義を確実に提供します。また、グローバル名前空間内でこれらの名前を提供する場合があります。ヘッダー<stdlib.h>は、C標準と同じように、グローバル名前空間内で同じ宣言と定義を確実に提供します。名前空間std内でこれらの名前を提供する場合もあります。 —例の終了]

14
Alok Save
  1. cstdintはC++ 11ヘッダー、stdint.hはC99ヘッダーです(CとC++は異なる言語です!)

  2. MSVC 2008にはstdint.hcstdintも含まれていません。

  3. cstdintの実装は、主に#include <stdint.h>であり、いくつかの名前空間/言語の修正があります。

0
hate-engine