web-dev-qa-db-ja.com

size_tにstddef.hまたはcstddefを含める必要があります

C++でsize_tを使用する場合、<stddef.h>または<cstddef>を含める必要がありますか? <cstddef>は悪い考えであり、非推奨にする必要があると言う人が何人かいます。何故ですか?

26
fredoverflow

私は_#include <stddef.h>_が好きです。

Cヘッダーの名前の一部はマクロにすることができますが、セットはCルールとは異なります。 Cでは、_EXIT_FAILURE_、isdigit()getc() a.o.マクロです。 C++のマクロはどれか知っていますか?

次に、_<cfoo>_ヘッダーを持つために必要な標準Cヘッダーは2つだけですが、Posixヘッダーは必要ありません。どのヘッダーが標準で、どのヘッダーがコンパイラーによってのみ提供されるか知っていますか?

第三に、サードパーティのCライブラリのヘッダーを使用すると、最終的に_#include <stddef.h>_になり、_<stddef.h>_と_<cstddef>_を混在させたくない。

第4に、新しいC++標準の現在のドラフトでは、_<cstdlib>_はシンボルをグローバル名前空間にダンプできるとされているため(最近では多くのコンパイラがすでにそうしているようです)、_#include <cstdlib>_を使用してもグローバル名前空間は将来汚染されないでしょう。したがって、ポータブルコードを作成するときは、グローバル名前空間が影響を受けると想定することをお勧めします(現在は許可されていませんが)。これを知っている専門家はごくわずかであるため(ここのコメントの説明を参照)、初心者のC++プログラマーでもグローバル名前空間を汚染することを理解するため、_<stddef.h>_を使用することをお勧めします。

13
Sjoerd

stddef.hはCヘッダーです。名前size_tは、その中のグローバル名前空間にあります。一方、<cstddef>はC名をstd名前空間にラップするC++ヘッダーであり、これは当然C++アプローチであるため、<cstddef>を含め、コンパイラが準拠している場合は、 std::size_tを使用します。明らかに、C++では、C++アプローチの方が適切です。 HTH

編集:技術的には、Cヘッダーもmay std名前空間の名前を含みます。ただし、Cヘッダー(.hで終わるもの)は、using-declarationsを介してグローバル名前空間にも名前を導入します(したがって、名前空間を汚染します)。

40
Armen Tsirunyan

<stddef.h>は正式にC++の非推奨部分です(C++標準のAnnex Dの残りの部分とともに)。これらはすべて(非推奨ではない)標準Cの一部であるため、C++で非推奨になったとしても、ほぼ無期限に利用できることはほぼ確実です。

そうではない非推奨の多くの機能が最初にほぼ確実に消えます-exportはすでにC++ 0xの現在のドラフトから削除されており、推測しなければならない場合は、例外仕様はAnnexDよりもはるかに多くなる可能性が高いと思います。これらのヘッダーが本当に廃止された場合、それはおそらく、David Vandervoordeのモジュール提案の成熟したバージョンからのものであり、簡単にレンダリングできますすべてヘッダーは廃止されました。

同時に、かなりの数のコンパイラ(特に古いコンパイラ)は、標準で規定されているとおりに<c*>ヘッダーを実装していません。それらで動作するコードを記述したい/必要な場合は、<*.h>ヘッダーの代わりに<c*>ヘッダーを使用することでかなりの利益が得られます。

最終的には、<c*>ヘッダーが問題を探すための解決策だったと思います。 C標準では、これらのヘッダーが必要な名前を定義する必要がありますのみ必要な名前を定義します-先頭のアンダースコアの後に別のアンダースコアまたは大文字が続くなど、予約されている名前以外はまったくありません。予約された名前(およびその他のいくつか)はC++でも予約されているため、どのような場合でもポータブルコード内の名前と衝突することはありません。そのため、すべての<c*>ヘッダーは、C標準ライブラリの既存の名前と衝突するグローバル名前空間の名前を定義する機能です。それは非常にひどい考えであり、検討する価値すらありません。したがって、実用的な観点からは、何も得られていません。

編集:その役に立たない機能でさえ、アップコーミングC++ 0xの現在のドラフトが<c*>ヘッダーにグローバル名前空間を汚染する許可を与えるのに十分な数の実際のコンパイラで機能したため、理論上の利点さえなくなりました。

11
Jerry Coffin

どちらも標準であり、AFAIKはそこにとどまります。

フォームcXXXは常にstd名前空間に名前を導入し、フォームXXX.hは常にグローバル名前空間に名前を導入します。どちらも名前を他の名前空間に配置する場合があります(少なくともC++ 0Xでは、以前はそうではありませんでした。その制約を尊重すると、制御していないCライブラリからC++ライブラリを構築できなくなります。制約が削除されました。g++は、少なくともglibc以外のターゲットでその問題を抱えています)。

従来のUnixヘッダーの場合、すべての実装でテストしました。必要な機能マクロが以前に定義されている場合は、XXX.hに追加のUnix識別子が含まれます。フォームcXXXの動作は、実装間で一貫していませんでした。したがって、実際には、これらの宣言が必要になることが多いため、XXX.hを使用します。

2
AProgrammer