- C ++プログラムには何を含める必要があります
stdio.h
かcstdio
?なぜ? - 同じ機能を提供する2つのヘッダーファイルはなぜですか?
- 規格はこれに関して何と言っていますか?
- 他のそのようなヘッダーを含めるにはどうすればよいですか?従う必要のある基本ルールはありますか?
2 に答える
次のプログラムを検討してください。
#include<stdio.h>
int main()
{
printf("Hello World");
return 0;
}
#include<cstdio>
int main()
{
printf("Hello World");
return 0;
}
どちらも期待どおりに機能します。では、どちらの使用法がより適切ですか? 答えは:どちらでもない!驚いた?読む。
C ++標準ライブラリは、互換性の理由からすべての標準Cヘッダーを提供しますが、言語としてのC++もすべての同等のヘッダーを提供します。慣例として、
- C ++標準ライブラリヘッダー(C互換性のために含まれているものを除く)にはファイル拡張子がなく、
- Cヘッダーに相当するすべてのC++は、で始まります
cxxxxx
。
C ++標準では、これについてAnnex D(標準)互換性機能で言及されています。
§2は重要な区別点に言及しています。上記の例に適用されるこのルールは、次のことを意味します。
- cstdioを含めると、シンボル名がstd名前空間にインポートされ、場合によってはグローバル名前空間にインポートされます。
- stdio.hを含めると、シンボル名がグローバル名前空間にインポートされ、場合によってはstd名前空間にインポートされます。
このルールをサンプルコードに適用して、長所と短所を測定しましょう。
サンプル1: これにより、グローバル名前空間のstdio.hからすべてのシンボルが取得されます。利点は、シンボルがグローバル名前空間にインポートされるため、修飾なしでシンボルを使用できることです。欠点は、おそらく決して使用しないであろう多くのシンボル名でグローバル名前空間を汚染してしまうことです。これにより、シンボル名が衝突する可能性があります。C ++では、常にグローバル名前空間を地雷原と見なし、可能な限り回避します。
サンプル2: 実装がシンボルをグローバル名前空間に配置するという保証がないため、これは非常に悪い習慣です。標準では、そうすることを要求していません。ある特定のコンパイラ実装の動作に依存しているだけです。すべてのコンパイラがそうすることを想定することはできませんし、想定すべきではありません。したがって、厳密に言えば、プログラムは標準で承認されておらず、この使用法はすべての実装間で移植可能ではありません。
では、正しい使用法は何ですか?
正しい使用法は、シンボル名を使用して完全に修飾するか、宣言cstdio
を使用してそれらをスコープに含めることです。これにより、使用するすべてのシンボルが名前空間に存在し、グローバル名前空間を汚染しないことが保証されます。正しい使用例:using
std
#include<cstdio>
using std::printf;
int main()
{
printf("Hello World");
return 0;
}
using namespace std;
特にヘッダー内のディレクティブは適切なオプションではないため、常にusing
宣言を使用する必要があることに注意してください。
stdio.h
ここではサンプルcstdio
のユースケースと見なしていることに注意してください。実際には、とのようなものを除いて、ほとんどすべてのcxxxx
ヘッダーxxxx.h
に適用されます。<math.h>
<cmath>
この投稿は少し古いので、私は以下を共有したいと思いました:
コードを見る:
Using X.h // Compatible with C language standard
---------------
#include <X.h>
int main() {
// Invoke X's corresponding function
return 0;
}
Using X // Not compatible with C language standard
--------------
#include <X>
int main() {
// Invoke X's corresponding function
return 0;
}
それらは両方ともコンパイルして実行します。
C ++でどちらが優れていますか?
C++11およびC++17の仕様について:
C.5.1(C ++ 17ドキュメントのセクション)
ヘッダーの変更[diff.mods.to.headers]
- C標準ライブラリとの互換性のために、C ++標準ライブラリはD.5で列挙されたCヘッダーを提供しますが、C++ではそれらの使用は非推奨です。
<stdatomic.h>
Cヘッダー、、、<stdnoreturn.h>
およびのC ++ヘッダーはなく<threads.h>
、Cヘッダー自体もありません。
C++の一部。
- C ++ヘッダー
<ccomplex>
(D.4.1)と<ctgmath>
(D.4.4)、およびそれらに対応するCヘッダー<complex.h>
と<tgmath.h>
は
C標準ライブラリのコンテンツのいずれかを含み、代わりにC++標準ライブラリの他のヘッダーを含めるだけです。
D.5C 標準ライブラリヘッダー[depr.c.headers]
- C標準ライブラリとの互換性のために、C++標準ライブラリは表141に示すCヘッダーを提供します。
C++11とC++17の両方の標準仕様書に<X.h>
は、C標準との互換性のためにremainを使用することが記載されていますが、それらの使用は非推奨と見なされています。
C++20標準提案について
彼らは、C++20でのCライブラリヘッダーの使用を「評価しない」ことを検討しています。<X.h>
緑色で強調表示されます。現在のところ、C++11およびC++17の非推奨は「弱い推奨事項」として示され、「 C標準ライブラリヘッダー(c.headers) 」を維持するための「微調整」が以下に表示されます。
「基本的なCライブラリヘッダーは重要な互換性機能であり、すぐにはどこにも行きません。」(C ++ 20レビュードキュメントから)
D.5C標準
ライブラリヘッダー[depr.c.headers]弱い推奨事項:
<stdatomic.h>
上記に加えて、対応する、、、<stdnoreturn.h>
または、ヘッダーがないのと同様に、対応するCヘッダーもC++標準から削除し<threads.h>
ます。上記と同じですが、次の調整が加えられています。20.5.5.2.1C標準ライブラリヘッダー[c.headers]C標準ライブラリとの互換性のために、C++標準ライブラリは表141に示すCヘッダーを提供します。表141—Cヘッダー
<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h>
<complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h>
<ctype.h> <limits.h> <stdarg.h> <string.h>
<errno.h> <locale.h> <stdbool.h> <tgmath.h>
<fenv.h> <math.h> <stddef.h> <time.h>
<float.h> <setjmp.h> <stdint.h> <uchar.h>
ヘッダー
<complex.h>
は、単にヘッダーが含まれているように動作し<complex>
ます。ヘッダー<tgmath.h>
は、単にヘッダー<complex>
とを含むかのように動作し<cmath>
ます。
Bjarne Stroustrupは、非互換性を可能な限り減らすことにより、C言語とC++言語間の相互運用性を最大化することを推奨しています。それが物事を複雑にするので、他の人はそうではないと主張します。
だから、どこにも行か<X.h>
ないようです。最終的には、両方を使用できます。個人的には、どちらを使用するかを決定するのは、コードをCコードと下位互換性があるかどうかです。