18

私はclass と struct の違いをよく知っていますが、これが明確に定義されているかどうかを正式に言うのに苦労しています:

// declare foo (struct)
struct foo;

// define foo (class)
class foo {
};

// instance of foo, claiming to be a struct again! Well defined?
struct foo bar;

// mixing class and struct like this upsets at least one compiler (names are mangled differently)
const foo& test() {
   return bar;
}

int main() {
   test();
   return 0;
}

これが未定義の動作である場合、誰かが信頼できる (つまり、ISO の章と節) 参照の方向に私を向けることができますか?

これを処理するのに問題のあるコンパイラ ( Carbide 2.7 ) は比較的古く、私が試した他のすべてのコンパイラはこれに完全に満足していますが、明らかにそれは何も証明しません。

私の直感では、これは未定義の動作であるはずでしたが、これを確認するものを見つけることができず、GCC バージョンまたはコモーのどれもそれについて警告していないことに驚いています。

4

6 に答える 6

12

それは定義された振る舞いのように私には見えます。特に、§9.1/2は次のように述べています。

のみで構成されるclass-key identifier ;宣言は、現在のスコープ内の名前の再宣言、またはクラス名としての識別子の前方宣言のいずれかです。クラス名を現在のスコープに導入します。

class標準では、を使用するstructunion、クラスを定義するかを区別しますが、ここでは、宣言について説明しますが、そのような区別はありません。1つを使用class-keyすることは他と同等です。

于 2011-02-01T19:04:53.510 に答える
6

言語標準によれば、技術的にはコードは問題ありません。ただし、最も人気のあるコンパイラの少なくとも1つがこれに対して警告を発行するため、実際には機能しません。

「理論的には、理論と実践の間に違いはありません。実際には、違いがあります。」

于 2011-02-03T00:11:30.687 に答える
4

警告C4099から:'class'を使用して最初に見られたタイプ名'struct'を使用して見られるようになりました(MS VS 2k8)少なくとも一部のコンパイラは、使用されるキーワードに応じて異なる方法でマングルするようです。したがって、技術的に許可されている場合でも、それに依存しないことをお勧めします(確認用の参照が見つかりません)。

于 2011-02-01T19:05:57.427 に答える
3

C++ では、構造体はクラスです。具体的には:

構造体は、 class-key で定義されたクラスstructです。(ISO/IEC FDIS 14882:1998(E) 9-4)

これは、で定義されていないクラスstructが確実に構造体ではないことを意味します。したがって、struct class-key を使用した前方宣言は誤りです。前方宣言が明らかに間違っているクラスキーを使用することを許可する仕様のどの部分も認識していません。問題の寛大なコンパイラは、構造体とクラスを同等に扱い、間違った宣言を見逃しているに違いありません。このシナリオでは、コンパイラからのエラーは必要ないかもしれませんが、予期しないものでもありません。

于 2011-02-01T18:43:28.023 に答える
0

これが C 標準に従って未定義 (または厳密に準拠していない他のカテゴリのいずれか) であるかどうかはわかりませんが、タイプが ' foo' は、次のように「クラス」または「構造体」として宣言されます。

TU 1

struct foo;
void f(foo&) { ... }

TU 2

class foo { ... };
void f(foo&);

void g()
{
  foo x;
  f(x);
}

次に、少なくとも一部のコンパイラ (特に MSVC++) は、f翻訳単位ごとに の名前を異なる方法でマングルするため、fTU 1 の の定義は TU 2 の への参照を満たさずf、リンク エラーが発生します。A.hこれは、 class を定義するヘッダーがありA、 classes BC、およびを参照する必要Dがあるが、それらの前方宣言で十分である場合に実際に発生します (したがって、非常に賢明なことに、 etc は含まれませB.h)。同じキーワードを使用することをお勧めします。実際の定義が行う前方宣言のために!

于 2011-02-01T18:35:24.900 に答える
0

MSVC10 は警告をスローし、警告ページには、定義で指定された型が使用されることが示されます。

http://msdn.microsoft.com/en-us/library/695x5bes.aspx

于 2011-02-01T18:43:48.923 に答える