-1

たとえば、アラインメントの可能性があるため、異なる型へのポインターを互いに直接変換することはできません (完全に正しいステートメントではないかもしれませんが、とにかく私の考えはわかりません)。次のようなことができないという同様の技術的な理由はありますか?

struct A
{
    int a, b;
} ;

struct B
{
    int a, b;
} ;

void func(struct A a, struct B b)
{
    a = b;
}

今すぐ私を削除して、この質問を編集して(奇妙なケースで)理解し、一般に翻訳してください。

4

2 に答える 2

1

C 標準では「型の互換性」が定義されており、構造体の型が互換性を持つためには、他の基準の中でも特に、同じタグを使用する必要があります。構造は異なるタグを使用します — それらは本質的に異なるタイプです。

標準のいくつかの複雑な言葉遣いの仕様で、下品な詳細を見つけることができます。

ISO/IEC 9899:2011 §6.2.7 互換型と複合型

型が同じ場合、2 つの型には互換性のある型があります。2 つの型に互換性があるかどうかを判断するための追加の規則は、型指定子については 6.7.2 で、型修飾子については 6.7.3 で、宣言子については 6.7.6 で説明されています。55)さらに、別々の翻訳単位で宣言された 2 つの構造体、共用体、または列挙型は、それらのタグとメンバーが次の要件を満たしている場合に互換性があります。両方がそれぞれの翻訳単位内のどこかで完了する場合、次の追加要件が適用されます。対応するメンバーの各ペアが互換性のある型で宣言されるように、メンバー間に 1 対 1 の対応が必要です。ペアの一方のメンバーがアライメント指定子で宣言されている場合、もう一方は同等のアライメント指定子で宣言されています。ペアの一方のメンバーが名前で宣言されている場合、もう一方は同じ名前で宣言されます。2 つの構造体の場合、対応するメンバーは同じ順序で宣言する必要があります。2 つの構造体または共用体の場合、対応するビットフィールドは同じ幅でなければなりません。2 つの列挙の場合、対応するメンバーは同じ値を持つ必要があります。

55)互換性があるために、2 つのタイプが同一である必要はありません。

2 つのサンプル構造には異なるタグ ( struct Astruct B) があるため、明らかに互換性のある型ではありません。

2 番目の例では、2 つの匿名struct型を使用します。

struct { int a, b; } func1();

void func2()
{
    struct { int a, b; } var = func1(); //not allowed
}

標準の別の部分がこれに適用されます。

6.7.2.1 構造体および共用体指定子

¶8 struct-or-union-specifier に struct-declaration-list が存在すると、翻訳単位内で新しい型が宣言されます。struct-declaration-list は、構造体または共用体のメンバーの一連の宣言です。

参照するstruct-declaration-listは中かっこ{…で囲まれた部分です}。1 つの翻訳単位に 2 つあるため、2 つの型を宣言 (定義) するため、互換性がありません。

あなたの最後の例は、 C では新しい型を導入しないことtypedef int myOrangeInt;typedef int myAppleInt;示しています。typedef別のタイプのシノニムを導入するだけです。この場合、myOrangeIntは のシノニムでintあり、 もmyAppleInt同様であり、これらは同じ型のシノニムであるため、型は同じ型です。

§6.7.8 型定義

¶3 …typedef宣言は新しい型を導入するのではなく、そのように指定された型のシノニムのみを導入します。…</p>

于 2016-03-03T00:44:13.160 に答える
1

cでは、同じコンテキストを持つ2つの異なる構造が実際に異なる型を作成できるのはいつですか?

彼らはいつもそうします。 struct Astruct B、異なるタイプです。

struct A {
    int a, b;
} ;

struct B {
    int a, b;
} ;

これが禁止されている理由は、純粋にコンパイラにとって複雑すぎるという事実ですか、それとも何か他のことですか?

コンパイラにとって複雑すぎません。それらを別々に保管することが望ましいです。同じにする必要がある場合は、コードで を使用できますtypedef

typedef struct A foo;
typedef struct A bar;

int main(void) {
  foo1 x;
  bar1 y = x;
  struct B z = x; // does not compile
}

なぜ許可しないのstruct B z = x;ですか?それが言語設計です。以下のような愚かなコードを防ぐ場合。struct JustLikeFILEと同じフィールドがありますが、FILE概念的には ではありませFILE

void f(void) {
  FILE *f = fopen("abc","r");
  struct JustLikeFILE g = *f;  // does not compile
}
于 2016-03-02T23:34:29.537 に答える