5

The C++ Programming Language : Special Edition の 431 ページには、次のように記載されています。

For every header < X.h > defining part of the C standard library in the global namespace and also in namespace std, there is a header < cX > defining the same names in the std namespace only.

ただし、< cX > スタイルで C ヘッダーを使用する場合、名前空間を修飾する必要はありません。例えば...

#include <cmath>
void f() {
  double var = sqrt( 17 );
}

これは正常にコンパイルされます。この本では、 < cX > ヘッダーを使用すると std 名前空間でのみ名前が定義されると書かれていますが、名前空間を修飾せずにそれらの名前を使用することは許可されています。ここで何が欠けていますか?

PS GNU.GCC コンパイラの使用

4

5 に答える 5

9

MSVC チームのメンバーである Stephan T. Lavavej は、彼のブログ投稿 ( http://blogs.msdn.com/vcblog/ archive/2008/08/28/the-mallocator.aspx#8904359 ):

> また、<cstddef><cstdlib>std::size_tなどを使用する必要があります。

私はそれについて非常に注意を払っていました。<cfooC++98 には、 > が名前空間 std 内ですべてを宣言し、すべて<foo.h>を含め<cfoo>てから、using 宣言を使用してグローバル名前空間にドラッグするという素晴らしい夢がありました。(これは D.5 [depr.c.headers] です。)

これは多くの実装者によって無視されました (一部の実装者は C 標準ライブラリ ヘッダーをほとんど制御できませんでした)。そのため、C++0x は現実に合わせて変更されています。N2723 Working Paper ( http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf )の時点で、<cfoo>名前空間 std 内のすべてを宣言することが保証され、何かを宣言する場合と宣言しない場合があります。グローバル名前空間内。<foo.h>は逆です。グローバル名前空間内ですべてを宣言することが保証されており、名前空間 std 内で何かを宣言する場合と宣言しない場合があります。

実際には、C++0x では、<cfoo>インクルードはグローバル名前空間で宣言されるすべてのものに対する安全策ではありません。それが私が気にするのをやめている理由です<cfoo>

これは Library Issue 456、http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456でした。

(C++0x はまだ<foo.h>C 標準ライブラリのヘッダーを非推奨にしていますが、これは面白いことです。)

私は Lavavej に 100% 同意していますが、<cfoo>私が C++ を使い始めたばかりのときでさえ、スタイル ヘッダーの使用に細心の注意を払ったことは一度もありませんでした。 (そして、<cfoo>スタイルヘッダーを使用することによる実際の利点はないようです)。

于 2010-01-22T16:28:16.290 に答える
6

C ライブラリのルールは、名前空間の C++ ライブラリとは異なります

gcc は、 Gcc docsの標準を次のように解釈します。

標準では、C スタイルのヘッダー (この場合は <math.h>) が含まれている場合、シンボルはグローバル名前空間およびおそらく名前空間 std:: で使用できると指定されています (ただし、これはもはや確固たる要件ではありません)。一方、C++ スタイルのヘッダー (<cmath>) を含めることで、エンティティが名前空間 std およびおそらくグローバル名前空間で見つかることが保証されます。

ドラフトC0X++仕様では、セクション17.6.2.3ヘッダーに記載されています

これらの名前が最初にグローバル名前空間スコープ内で宣言され、次に明示的な using 宣言によって名前空間 std に注入されるかどうかは指定されていません

于 2010-01-22T16:03:25.763 に答える
4

C ライブラリを 2 回実装せずにこれを修正するのは困難です。基本的にこの問題をあきらめることを提案しているDR 456を参照してください。

于 2010-01-22T16:03:24.850 に答える
1

標準に違反しているのに、なぜ「これはうまくコンパイルされるだろう」と言うのですか?名前空間を修飾せずにこれらの名前を使用できるのは誰ですか?これを特定の実装でテストし、機能することを確認しましたか?

選択したコンパイラで動作するため、特定の非標準機能を使用しないことを強くお勧めします。おそらく同じコンパイラの新しいバージョンでは、そのようなことは簡単に壊れます。

于 2010-01-22T15:54:02.213 に答える
0

標準に準拠したコンパイラを使用していない可能性があります (または、使用しているコンパイラが標準化前のコードと互換性があるように構成されています)。

于 2010-01-22T15:52:33.630 に答える