8

誰かが次のことを説明してくれませんか:

$ cat test.cpp 
#include <string>
std::string div;
$ g++ -c test.cpp 
$ g++ -std=c++11 -c test.cpp 
test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol
In file included from /usr/include/c++/4.7.1/cstdlib:66:0,
                 from /usr/include/c++/4.7.1/ext/string_conversions.h:37,
                 from /usr/include/c++/4.7.1/bits/basic_string.h:2814,
                 from /usr/include/c++/4.7.1/string:54,
                 from test.cpp:1:
/usr/include/stdlib.h:787:14: error: previous declaration of 'div_t div(int, int)'
$

C++11 モードでも、divシンボルは名前空間にあるべきではありませんか? stdそれとも私のシステムに固有のものですか?

4

3 に答える 3

4

/usr/include/stdlib.h

.hC stdlib ヘッダー内のすべての名前は、 (明らかに) グローバル名前空間に存在します。

さらに、cHEADERC++ stdlib ヘッダーは、対応する名前を名前空間から定義しHEADER.hますstdが、それらをグローバル名前空間に含めることもできます (したがって、

// cHEADER
#include <HEADER.h>

namespace std{
using ::one_name_from_HEADER;
using ::another_name_from_HEADER;
// and so on...
}

そしてそれで終わりです)。

§D.5 [depr.c.headers]

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

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

ご覧のとおり、同じことが逆にも当てはまります (あたかも名前空間に<HEADER.h>名前を導入することがありますstd

// HEADER.h
#include <cHEADER>

using std::one_name_from_HEADER;
using std::another_name_from_HEADER;
// and so on...
}

)、これにより、これらのヘッダーが完全に区別されます...実際には役に立ちません。

于 2012-10-23T22:25:30.383 に答える
3

divからの関数です<stdlib.h>

C++11 では、<c何とか>ヘッダーがグローバル名前空間に何かを配置することが許可されていました。

C++11 §17.6.1.2/4 :
「条項 18 から 30 および付属書 D に記載されている場合を除き、各ヘッダーの内容は、C 標準ライブラリ (1.2) で指定されている対応するヘッダーの内容と同じでなければならない」または必要に応じて、C Unicode TR を含めるかのように。ただし、C++ 標準ライブラリでは、宣言 (C でマクロとして定義されている名前を除く) は、名前空間の名前空間スコープ (3.3.6) 内にあります。これらの名前が最初にグローバル名前空間スコープ内で宣言され、次に明示的なusing 宣言(7.3.3) によって名前空間 std に挿入されるかどうかは不明です。」cnamename.hstd

一般的な C++ 実装の現実を反映しています。

したがって、形式的なことを除いて、実際には何も変更されていません。表示される動作は、許容しなければならない実装アーティファクトではなく、標準によって承認されているということです。

また、正式な変更により、 xxx.hヘッダーではなくヘッダーを含めた方がよいという SO に関する議論が容易になります…c

于 2012-10-23T22:21:50.067 に答える
1

17.6.4.3.3/1 の状態:

ヘッダーで外部リンケージを持つオブジェクトとして宣言された各名前は、名前空間とグローバル名前空間の両方で、外部リンケージを持つそのライブラリ オブジェクトを指定するために実装用に予約されています。std

divヘッダー cstdlib で外部リンケージを持つ関数として宣言された名前であるため、グローバル名前空間で予約されている名前です。この名前の使用は許可されていません。

于 2012-10-23T22:54:02.387 に答える