6

どうやら、

C の前史にまで及ぶ理由により、同じスコープ内で同じ名前の構造体と非構造体を宣言することが可能です。- ( Bjarne Stroustrup - C++ プログラミング言語。第 4 版)

例えば:

struct Ambig {};

// the struct must be referred to with the prefix struct
void Ambig(struct Ambig* buf) {}

最初の理由は何だったのか気になります。理解しないと、あいまいさを引き起こし、混乱を招く悪い言語設計の例のように思えます。

4

4 に答える 4

6

その理由は、Stroustrup からの引用で述べたように、歴史的なものです。C では、常に構造体の名前の前に;を付ける必要があります。struct構造体の名前 (共用体や列挙型の名前など) はタグと呼ばれ、他のシンボルとはまったく異なる名前空間に存在します。次のようなもの:

struct stat
{
    //  ...
};
int stat( char const* filename, struct stat* buf );

完全に合法です。(実際、上記は Posix の一部です)。

C++ では、( classstructまたは で宣言されたunion) クラスの名前または列挙型は他のすべてのものと同じ名前空間にあり、C とは異なり、次のように記述できます。

struct MyClass {};
MyClass variableName;

これは正当な C ではありません。C では、2 行目は次のようにする必要があります。

struct MyClass variableName;

問題は、C++ が C で定義されたインターフェース (上記の Posix インターフェースなど) を使用できる必要があることです。そのため、C++ ではそれを可能にする特別な規則がいくつか定義されています。変数または関数とクラス型に同じ名前を付けることができます。これを行うと、変数または関数名が優先され、クラス名が非表示になります。ただし、「詳細な型指定子」(つまりclassstructunionまたはenumの後に記号が続く) を除きます。この場合、型以外の名前はルックアップで無視されます。

于 2013-08-15T09:12:56.120 に答える
3

最初の理由は何だったのか気になります。理解しないと、あいまいさを引き起こし、混乱を招く悪い言語設計の例のように思えます。

C では、名前空間の最初の実装です。識別子は異なる名前空間に存在し、異なる名前空間で宣言されている場合、同じ名前を持つことができるという考え方です。構造タグと通常の識別子の名前空間は、C の 2 つの名前空間だけではありません。C には 4 つの名前空間があります。

(C99, 6.2.3 識別子の名前空間 p1) 「したがって、次のように、さまざまなカテゴリの識別子に対して個別の名前空間があります。

— ラベル名 (ラベルの宣言と使用の構文によって曖昧さが解消されます);

— キーワード struct、union、または enum の構造体、union、および列挙のタグ (any24 に従うことで明確化);

— 構造体または組合のメンバー 各構造体または共用体には、そのメンバー用の個別の名前空間があります (. または -> 演算子を介してメンバーにアクセスするために使用される式のタイプによって曖昧さが解消されます)。

— 通常の識別子と呼ばれる他のすべての識別子 (通常の宣言子または列挙定数として宣言されます)。

于 2013-08-15T09:11:45.627 に答える
3

このような理由は、C から継承した C++ に関係しています。C++ に「追加」されたのではなく、C でそのように機能するため、そこにあります。

C では、struct Xand union Y( classC にはキーワードがありません) を使用するか、代わりにtypedef struct X A;名前を使用して使用する必要があります(X と A は同じ名前である可能性があります)。Astrcut X

C++ では、名前が一意である限り、コンパイラはXが を参照していることを理解しstruct Xます。名前の前にや を入力structunionたり、新しいスタンドアロンの名前を作成するために使用したりする必要はありません。classtypedef

C++ は (可能な限り) C 構文の使用を許可するように設計されてstruct Xいるため、構造体を参照する場合でも書き込みが許可されます。これにより、あいまいな名前を使用できるようになります。

歴史的な設計上の決定で必要とされない限り、この「可能性」を利用しないことを強くお勧めします。

于 2013-08-15T09:09:33.740 に答える
1

構造体の前に追加することstructは完全に正当な C です。したがって、一部の C コードは C++ にも適用されます。
何を期待していましたか?C++ は C をベースにしています。

C++ では、structすべての構造体の前に使用することを避けています。実際に製品コードで見たことはありません。

あいまいさに関しては、なぜそれを許可したのか、誰も知らないと思います。しかし、追加するとあいまいさが解決されるためだと思いますstructpossible meaning基本的に、これは関数ではないため、削除されることをコンパイラに伝えます。

于 2013-08-15T08:49:21.653 に答える