Ist eine Deklaration einer unmarkierten Struktur ein kompatibler Typ?

9

Für Zwecke, die in diese Frage ausgedrückt sind, wir wollen das tun:

%Vor%

Der Wunsch ist, dass die Casts C 2011 entsprechen 6.7.2.1 15 , die besagt: "Ein Zeiger auf ein Strukturobjekt, das entsprechend konvertiert wurde, zeigt auf sein Anfangselement (oder wenn dieses Element ein Bitfeld ist, dann auf die Einheit, in der es sich befindet) und umgekehrt."

Da struct { int a; } in B keinen Namen hat, nennen wir es A' .

"Suitably" ist nicht explizit definiert. Ich nehme an, dass, wenn A * ein gültiger Zeiger auf ein Objekt vom Typ A' ist, (A *) b eine geeignete Konvertierung durchführt, und, wenn a ein Zeiger auf eine A' ist, die in% ist co_de%, dann ist B eine geeignete Konvertierung.

Die Frage ist also: Ist (B *) a ein gültiger Zeiger auf ein Objekt vom Typ A * ?

Pro 6.7.6.1 , A' ist kompatibel mit A * wenn A' * mit A kompatibel ist.

Pro 6.2.7 , "Zwei Typen haben einen kompatiblen Typ für ihre Typen sind gleich ... Darüber hinaus sind zwei Struktur-, Vereinigungs- oder Aufzählungstypen, die in separaten Übersetzungseinheiten deklariert sind, kompatibel, wenn ihre Tags und Member die folgenden Anforderungen erfüllen: Wenn einer mit einem Tag deklariert ist, muss der andere mit demselben Tag deklariert werden. Wenn beide innerhalb ihrer jeweiligen Übersetzungseinheiten abgeschlossen sind, gelten die folgenden zusätzlichen Anforderungen: zwischen ihren Mitgliedern muss eine Eins-zu-eins-Korrespondenz bestehen, so dass jedes Paar entsprechender Mitglieder mit kompatiblen Typen deklariert wird; Wenn ein Mitglied des Paars mit einem Ausrichtungsspezifizierer deklariert ist, wird der andere mit einem entsprechenden Ausrichtungsspezifizierer deklariert. und wenn ein Mitglied des Paares mit einem Namen deklariert ist, wird das andere mit dem gleichen Namen deklariert. Für zwei Strukturen müssen entsprechende Mitglieder in derselben Reihenfolge deklariert werden ... "

Diese können nicht vom selben Typ sein wie in 6.7.2.3 5 : " Jede Deklaration einer Struktur, Union oder eines Aufzählungstyps, der kein Tag enthält, deklariert einen eindeutigen Typ. "

Da sie nicht vom selben Typ sind, sind sie kompatibel? Der Text in 6.2.7 besagt, dass sie kompatibel sind, wenn sie in separaten Übersetzungseinheiten deklariert sind, aber diese sind in der gleichen Übersetzungseinheit.

    
Eric Postpischil 25.01.2018, 14:47
quelle

3 Antworten

1

Wie Sie in der Frage dargelegt haben, besagt der Standard klar und eindeutig, dass zwei Strukturdefinitionen struct { int a; } in derselben Übersetzungseinheit zwei inkompatible Typen deklarieren. Ungeachtet der Tatsache, dass dies "seltsam" sein könnte. Compiler haben sich immer an den Standard gehalten .

Das scheint mir ein vernünftiges Verhalten zu sein: Wenn Sie in Ihrem Projekt semantisch nicht verwandte Strukturen haben, die zufälligerweise eine Memberliste mit den gleichen Typen haben, möchten Sie, dass der Compiler eine zufällige Zuweisung zwischen den beiden zurückweist.

>

Re. der Code in Ihrer Frage, gemäß 6.7.2.1/13,

  

Die Mitglieder einer anonymen Struktur oder Vereinigung werden als Mitglieder der enthaltenden Struktur oder Vereinigung betrachtet.

Also würde ich die Definition von B als äquivalent behandeln zu:

%Vor%

für weitere Analysen.

    
M.M 03.03.2018, 22:59
quelle
1

Ich habe nichts in dem Standard gesehen, der besagt, dass beide struct kompatibel sind und daher würde ich sagen, dass sie nicht sind.

Das einzige, was Ihnen eine begrenzte Kompatibilität zwischen den Strukturen bringen könnte, ist die Verwendung einer Union, wie in 6.7.2.1§6 erwähnt:

  

Eine besondere Garantie wird gemacht, um den Gebrauch von Gewerkschaften zu vereinfachen: wenn eine Gewerkschaft enthält   mehrere Strukturen, die eine gemeinsame Anfangssequenz teilen (siehe unten), und wenn die Union   Objekt enthält derzeit eine dieser Strukturen, es ist erlaubt, das Gemeinsame zu inspizieren   Anfangsteil von irgendwelchen von ihnen überall, dass eine Erklärung des vollendeten Typs der Vereinigung   ist sichtbar.

d. h., etwas wie

%Vor%

sollte sicher sein, aber nur für Lesezugriffe: Der Standard hat sich nicht wirklich darum gekümmert zu spezifizieren, was "inspizieren" der gemeinsamen Anfangssequenz bedeutet, sondern scheint es in Gegensatz zu "modifizieren" zu benutzen.

    
Virgile 25.01.2018 16:55
quelle
0
___ answer484688800 ___

Es gibt zwei Situationen, in denen die Kompatibilität von Strukturen relevant ist:

  1. Bei der Entscheidung, ob Werte oder Zeiger eines Typs in Werte oder Zeiger des anderen Typs umgewandelt werden können, ohne den Casting-Operator zu verwenden und ohne eine Diagnose zu erstellen. Beachten Sie, dass zu diesem Zweck separat deklarierte Strukturen inkompatibel sind, auch wenn sie strukturell identisch sind. Diese Art der Kompatibilität ist jedoch beim Übergeben von Strukturen oder Zeigern zwischen Kompilierungseinheiten irrelevant.

  2. Bei der Entscheidung, ob ein Wert von oder ein Zeiger auf einen Typ sicher dem Code übergeben werden kann, der den anderen erwartet. Das Übergeben von Strukturen ohne Tags zwischen Kompilierungseinheiten wäre unmöglich, wenn strukturell identische Typen nicht als für diesen Zweck kompatibel betrachtet würden. Compiler verwendeten zu diesem Zweck auch innerhalb einer Kompilierungseinheit strukturell identische Typen als kompatibel, und es gab niemals einen guten Grund für Compiler, in Fällen, in denen eine oder beide Arten unmarkiert sind, etwas anderes zu tun, sondern weil der Standard dies nicht vorschreibt Behandlung Es ist in Mode gekommen, dass Compiler die Sprache sinnlos schwächen, indem sie blind annehmen, dass ein Zeiger auf einen solchen Typ nicht benutzt wird, um auf Mitglieder eines anderen zuzugreifen.

Leider, als der Standard geschrieben wurde, hielten es die Autoren nicht für wichtig, ausdrücklich alle offensichtlich nützlichen Dinge zu benennen, die Compiler bereits machten, und die vernünftige Compiler weiterhin tun würden. Das Endergebnis ist, dass nützliche Konstrukte, die früher unterstützt wurden und nicht kontrovers sind, unzuverlässig sind, es sei denn, ansonsten sind nützliche Optimierungen deaktiviert.

    
___ tag123c ___ C ist eine universelle Computerprogrammiersprache, die für Betriebssysteme, Bibliotheken, Spiele und andere Hochleistungsanwendungen verwendet wird. Dieses Tag sollte bei allgemeinen Fragen zur C-Sprache verwendet werden, wie in der Norm ISO 9899: 2011 definiert. Fügen Sie ggf. ein versionsspezifisches Tag wie c99 oder c90 für Fragen zu älteren Sprachstandards hinzu. C unterscheidet sich von C ++ und es sollte nicht mit dem C ++ - Tag kombiniert werden, wenn ein rationaler Grund fehlt. ___ qstntxt ___

Für Zwecke, die in diese Frage ausgedrückt sind, wir wollen das tun:

%Vor%

Der Wunsch ist, dass die Casts C 2011 entsprechen 6.7.2.1 15 , die besagt: "Ein Zeiger auf ein Strukturobjekt, das entsprechend konvertiert wurde, zeigt auf sein Anfangselement (oder wenn dieses Element ein Bitfeld ist, dann auf die Einheit, in der es sich befindet) und umgekehrt."

Da %code% in %code% keinen Namen hat, nennen wir es %code% .

"Suitably" ist nicht explizit definiert. Ich nehme an, dass, wenn %code% ein gültiger Zeiger auf ein Objekt vom Typ %code% ist, %code% eine geeignete Konvertierung durchführt, und, wenn %code% ein Zeiger auf eine %code% ist, die in% ist co_de%, dann ist %code% eine geeignete Konvertierung.

Die Frage ist also: Ist %code% ein gültiger Zeiger auf ein Objekt vom Typ %code% ?

Pro 6.7.6.1 , %code% ist kompatibel mit %code% wenn %code% mit %code% kompatibel ist.

Pro 6.2.7 , "Zwei Typen haben einen kompatiblen Typ für ihre Typen sind gleich ... Darüber hinaus sind zwei Struktur-, Vereinigungs- oder Aufzählungstypen, die in separaten Übersetzungseinheiten deklariert sind, kompatibel, wenn ihre Tags und Member die folgenden Anforderungen erfüllen: Wenn einer mit einem Tag deklariert ist, muss der andere mit demselben Tag deklariert werden. Wenn beide innerhalb ihrer jeweiligen Übersetzungseinheiten abgeschlossen sind, gelten die folgenden zusätzlichen Anforderungen: zwischen ihren Mitgliedern muss eine Eins-zu-eins-Korrespondenz bestehen, so dass jedes Paar entsprechender Mitglieder mit kompatiblen Typen deklariert wird; Wenn ein Mitglied des Paars mit einem Ausrichtungsspezifizierer deklariert ist, wird der andere mit einem entsprechenden Ausrichtungsspezifizierer deklariert. und wenn ein Mitglied des Paares mit einem Namen deklariert ist, wird das andere mit dem gleichen Namen deklariert. Für zwei Strukturen müssen entsprechende Mitglieder in derselben Reihenfolge deklariert werden ... "

Diese können nicht vom selben Typ sein wie in 6.7.2.3 5 : " Jede Deklaration einer Struktur, Union oder eines Aufzählungstyps, der kein Tag enthält, deklariert einen eindeutigen Typ. "

Da sie nicht vom selben Typ sind, sind sie kompatibel? Der Text in 6.2.7 besagt, dass sie kompatibel sind, wenn sie in separaten Übersetzungseinheiten deklariert sind, aber diese sind in der gleichen Übersetzungseinheit.

    
___ tag123languagelawyer ___ Für Fragen zu den Feinheiten formeller oder autoritativer Spezifikationen von Programmiersprachen und Umgebungen. ___ answer49090117 ___

Wie Sie in der Frage dargelegt haben, besagt der Standard klar und eindeutig, dass zwei Strukturdefinitionen %code% in derselben Übersetzungseinheit zwei inkompatible Typen deklarieren. Ungeachtet der Tatsache, dass dies "seltsam" sein könnte. Compiler haben sich immer an den Standard gehalten .

Das scheint mir ein vernünftiges Verhalten zu sein: Wenn Sie in Ihrem Projekt semantisch nicht verwandte Strukturen haben, die zufälligerweise eine Memberliste mit den gleichen Typen haben, möchten Sie, dass der Compiler eine zufällige Zuweisung zwischen den beiden zurückweist.

>

Re. der Code in Ihrer Frage, gemäß 6.7.2.1/13,

  

Die Mitglieder einer anonymen Struktur oder Vereinigung werden als Mitglieder der enthaltenden Struktur oder Vereinigung betrachtet.

Also würde ich die Definition von %code% als äquivalent behandeln zu:

%Vor%

für weitere Analysen.

    
___ qstnhdr ___ Ist eine Deklaration einer unmarkierten Struktur ein kompatibler Typ? ___ answer48448191 ___

Ich habe nichts in dem Standard gesehen, der besagt, dass beide %code% kompatibel sind und daher würde ich sagen, dass sie nicht sind.

Das einzige, was Ihnen eine begrenzte Kompatibilität zwischen den Strukturen bringen könnte, ist die Verwendung einer Union, wie in 6.7.2.1§6 erwähnt:

  

Eine besondere Garantie wird gemacht, um den Gebrauch von Gewerkschaften zu vereinfachen: wenn eine Gewerkschaft enthält   mehrere Strukturen, die eine gemeinsame Anfangssequenz teilen (siehe unten), und wenn die Union   Objekt enthält derzeit eine dieser Strukturen, es ist erlaubt, das Gemeinsame zu inspizieren   Anfangsteil von irgendwelchen von ihnen überall, dass eine Erklärung des vollendeten Typs der Vereinigung   ist sichtbar.

d. h., etwas wie

%Vor%

sollte sicher sein, aber nur für Lesezugriffe: Der Standard hat sich nicht wirklich darum gekümmert zu spezifizieren, was "inspizieren" der gemeinsamen Anfangssequenz bedeutet, sondern scheint es in Gegensatz zu "modifizieren" zu benutzen.

    
___
supercat 26.01.2018 20:08
quelle

Tags und Links