Ich habe diesen Code in einer Header-Datei für ein Gerät gefunden, das ich verwenden muss, und obwohl ich C seit Jahren mache, bin ich nie darauf gestoßen:
Ich bin mir nicht sicher, was der Sinn dieser Definition ist. Es ist in einer Header-Datei für eine Linux-Anwendung des Boards, aber ich bin verblüfft über die Verwendung. Irgendwelche Erklärungen, Ideen? Jeder hat das schon einmal gesehen (ich bin sicher, einige von euch haben es :).
Vielen Dank! :bp:
Deklaration der Speicherzuordnung
– Jebathon
10. Juli 2014 um 20:13 Uhr
Ich bin mir nicht sicher, was es bedeuten soll, aber es ist kein Standard; Die Syntax für eine Struct-Deklaration erfordert mindestens einen Member. Vielleicht ist es ein Platzhalter für zukünftige Erweiterungen?
Eine Möglichkeit besteht darin, dass es früher ein Mitglied in der Struktur “Gerät” gab, jemand dieses Mitglied gelöscht hat, weil es nicht mehr benötigt wurde, und vergessen hat, die Struktur zu löschen, oder es nicht gelöscht hat, weil es mehr Codeänderungen erforderte.
– Etienne
10. Juli 2014 um 21:15 Uhr
ouah
Dies ist nicht C, da C-Strukturen mindestens ein benanntes Mitglied enthalten müssen:
(C11, 6.7.2.1 Struktur- und Vereinigungsspezifizierer p8) “Wenn die Strukturdeklarationsliste keine benannten Mitglieder enthält, weder direkt noch über eine anonyme Struktur oder eine anonyme Vereinigung, ist das Verhalten undefiniert.”
aber eine GNU C-Erweiterung:
GCC erlaubt einer C-Struktur, keine Member zu haben:
Ich weiß nicht, was der Zweck dieses Konstrukts in Ihrem Beispiel ist, aber im Allgemeinen denke ich, dass es als Vorwärtsdeklaration des Strukturtyps verwendet werden kann. Beachten Sie, dass es in C++ erlaubt ist, eine Klasse ohne Member zu haben.
In Linux 2.4 gibt es ein Beispiel für einen leeren Strukturtyp mit bedingter Kompilierung in der Definition von spin_lock_t Geben Sie alias im Linux-Kernel 2.4 ein (in include/linux/spinlock.h):
Der Zweck besteht darin, Platz zu sparen, ohne die Funktions-API gegebenenfalls ändern zu müssen DEBUG_SPINLOCKS < 1. Es erlaubt auch, Dummy-Objekte (mit der Größe Null) zu definieren spinlock_t.
Ein weiteres Beispiel im (neueren) Linux-Kernel eines Hacks mit einer leeren Struktur, der mit bedingter Kompilierung in include/linux/device.h verwendet wird:
Es würde ein Problem beim Weiterleiten von Deklarationen im vom OP gesendeten Code geben: struct spi_device ist definiert (und nicht deklariert), daher muss der Compiler wissen, wie viel er dafür zuweisen muss.
– rslemos
10. Juli 2014 um 20:29 Uhr
@ouah Ich denke, wir kratzen uns alle am Kopf darüber, warum zum Teufel eine solche Definition jemals gemacht wird. Ich entschuldige mich für meinen Text; Wenn ich es jetzt noch einmal lese, fühlt es sich an, als würde ich Ihre Antwort kritisieren. Tut mir leid, das war ich nicht.
– rslemos
10. Juli 2014 um 20:34 Uhr
Ein Problem mit leeren Strukturen ist, wenn sie es auch haben sizeof Sein 0 dann verstößt ein Array davon gegen die Regel, dass unterschiedliche Objekte unterschiedliche Adressen haben müssen. Was passiert zum Beispiel mit struct device d[20], *ptr; for (ptr = d; ptr < d + 20; ++ptr) ?
– MM
10. Juli 2014 um 23:26 Uhr
@MattMcNabb – der Link zu gcc.gnu.org sagt “G++ behandelt leere Strukturen, als ob sie ein einzelnes Mitglied vom Typ char hätten”, also bezweifle ich sizeof jemals gleich wäre 0
– cegfehler
11. Juli 2014 um 6:22 Uhr
@cegfault: g++ kompiliert C++, und die Regeln dafür sind in C++ anders (ein weiteres Beispiel dafür, warum “C/C++”-Fragen vermieden werden sollten!)
– Leichtigkeitsrennen im Orbit
11. Juli 2014 um 9:19 Uhr
hackt
Das ist kein Standard-C. C11: 6.2.5-20:
— Ein Strukturtyp beschreibt eine sequentiell belegte nichtleere Menge von Mitgliedern Objekte (und unter bestimmten Umständen ein unvollständiges Array), von denen jedes einen optional angegebenen Namen und einen möglicherweise unterschiedlichen Typ hat.
J.2 Undefiniertes Verhalten:
Das Verhalten ist unter folgenden Umständen undefiniert:
….
— Eine Struktur oder Vereinigung wird ohne benannte Mitglieder definiert (einschließlich der indirekt über anonyme Strukturen und Vereinigungen spezifizierten) (6.7.2.1).
GCC verwendet es als Verlängerung (dort wird nicht genauer angegeben, wann/wo es verwendet werden sollte). Wenn Sie dies in einem beliebigen Programm verwenden, wird es Compiler-spezifisch.
Für den Datensatz erlaubt C++ dies ausdrücklich ([C++11: 9/1]).
– Leichtigkeitsrennen im Orbit
11. Juli 2014 um 9:18 Uhr
@LightnessRacesinOrbit; Ja. Ich weiss. Ich habe es vermieden, dies hinzuzufügen, weil nur das C-Tag vorhanden ist.
– Hacken
11. Juli 2014 um 9:29 Uhr
Yep hätte ich genauso gemacht. Wollte es nur anmerken 🙂
– Leichtigkeitsrennen im Orbit
11. Juli 2014 um 10:01 Uhr
Ein Grund, dies für eine Bibliothek zu tun, könnte sein, dass die Bibliotheksentwickler nicht möchten, dass Sie die Interna dieser Strukturen kennen oder in sie eingreifen. In diesen Fällen können sie eine “Schnittstellen”-Version der Strukturen bereitstellen spi_device/device (was Sie sehen können) und eine zweite Typdefinition haben, die eine andere Version dieser Strukturen zur Verwendung innerhalb der Bibliothek mit den tatsächlichen Mitgliedern definiert.
Da Sie mit diesem Ansatz nicht auf Strukturmitglieder zugreifen oder selbst kompatible Strukturen dieses Typs erstellen können (da selbst Ihr Compiler die tatsächliche Größe dieser Struktur nicht kennen würde), funktioniert dies nur, wenn die Bibliothek selbst die Strukturen erstellt und Sie immer nur übergibt verweist darauf, und Sie müssen keine Mitglieder ändern.
Klingt so, als würden Sie über undurchsichtige Strukturen sprechen – das heißt, eine Struktur, die deklariert, aber nicht definiert wurde, wie in struct device;. Aber die Frage zeigt etwas anderes: Die Struktur wurde als leer definiert.
– hmjail
13. Dezember 2016 um 15:59 Uhr
Wenn Sie eine leere Struktur als erstes Element einer anderen Struktur hinzufügen, kann die leere Struktur als “Markierungsschnittstelle” dienen, dh wenn Sie einen Zeiger auf diese äußere Struktur auf einen Zeiger der inneren Struktur umwandeln und die Umwandlung erfolgreich ist, wissen Sie das die äußere Struktur ist als etwas “markiert”.
Es könnte auch nur ein Platzhalter für zukünftige Entwicklungen sein, nicht sicher. Hoffe das hilft
Das ist gültiges C
struct empty;
struct empty *empty;
und erleichtert die Verwendung von Adressen undurchsichtiger Speicherbereiche.
Solche Adressen werden normalerweise von Bibliothekssubroutinen erhalten und an diese weitergegeben.
So etwas wird zum Beispiel in stdio.h gemacht
14094000cookie-checkC leere Struktur – was bedeutet/macht das?yes
Deklaration der Speicherzuordnung
– Jebathon
10. Juli 2014 um 20:13 Uhr
Ich bin mir nicht sicher, was es bedeuten soll, aber es ist kein Standard; Die Syntax für eine Struct-Deklaration erfordert mindestens einen Member. Vielleicht ist es ein Platzhalter für zukünftige Erweiterungen?
– Keith Thompson
10. Juli 2014 um 20:15 Uhr
Es scheint nichts zuzuordnen…
– Billy Pilgrim
10. Juli 2014 um 20:15 Uhr
Normalerweise ist es keine leere Struktur… Wie für warum Dies wurde in diesem Fall getan, es ist schwer zu sagen, ohne mehr Kontext.
– Maisstängel
10. Juli 2014 um 20:30 Uhr
Eine Möglichkeit besteht darin, dass es früher ein Mitglied in der Struktur “Gerät” gab, jemand dieses Mitglied gelöscht hat, weil es nicht mehr benötigt wurde, und vergessen hat, die Struktur zu löschen, oder es nicht gelöscht hat, weil es mehr Codeänderungen erforderte.
– Etienne
10. Juli 2014 um 21:15 Uhr