Was ist die Initialisierungssyntax für markierte Strukturen?

Lesezeit: 3 Minuten

Benutzeravatar von httpinterpret
httpinterpretieren

struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
.ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};

Diese Deklaration verwendet die Standard-C-Tag-Struktur-Initialisierungssyntax.

Kann jemand näher darauf eingehen?

  • Ich lese das gleiche Buch

    – Freiheit_Ben

    27. Januar 2014 um 0:17 Uhr

  • Ich lese das gleiche Buch zu

    – Lewis Z

    5. September 2017 um 2:25 Uhr

  • Ich lese das gleiche Buch auch 🙂

    – Guy Avraham

    16. Oktober 2017 um 10:53 Uhr

  • Für Neugierige ist dieses Codebeispiel von Linux-Gerätetreiberdritte Auflage, Kapitel 3Seite 53.

    – Harry Cutts

    3. Juli 2018 um 17:21 Uhr

  • Ich lese das gleiche Buch auch 2020 (:

    – Roi

    13. September 2020 um 14:32 Uhr

AnT steht mit Russlands Benutzer-Avatar
AnT steht zu Russland

Wenn Sie Aggregatinitialisierer verwenden (Initialisierer in {}) in der “traditionellen” ANSI-C-Sprache (C89/90) müssen Sie einen individuellen Initialisierer für jedes Strukturmitglied der Reihe nach bereitstellen, beginnend mit dem ersten. Zum Beispiel

struct S { int a, b, c, d; };

struct S s = { 1, 2, 3, 4 };
/* 1 for `s.a`, 2 for `s.b` and so on... */

Sie müssen keine Initialisierer für alle Member angeben, dh Sie können jederzeit aufhören (verbleibende Member werden mit Null initialisiert).

Wenn Sie aus irgendeinem Grund nur das dritte Mitglied der Struktur explizit initialisieren wollten, mussten Sie explizite “Dummy” -Initialisierer für das erste und das zweite Mitglied bereitstellen (nur um zum gewünschten dritten zu gelangen).

/* We only care to explicitly initialize `s.c` */
struct S s = { 0, 0, 3 };
/* but we have to explicitly initialize `s.a` and `s.b` as well */

oder die spezifische Initialisierung ganz aufgeben (wahrscheinlich durch generische ersetzen = { 0 }) und verwenden eine nachträgliche Zuordnung zu bestimmten Mitgliedern

struct S s = { 0 };
s.c = 3;

Ein bemerkenswerter Vorteil dieses auftragsbasierten Ansatzes besteht darin, dass er unabhängig von der Position des Mitglieds ist c in der Erklärung v struct S.

Die neue Spezifikation der C-Sprache (C99) ermöglicht Ihnen die Verwendung von „markierten“ Initialisierern, indem Sie den gewünschten Mitgliedsnamen innerhalb der angeben {}

struct S s = { .c = 3 };

Auf diese Weise initialisieren Sie nur die gewünschten Member explizit (und lassen den Compiler den Rest mit Null initialisieren). Das erspart Ihnen nicht nur etwas Tipparbeit, sondern macht die Aggregat-Initialisierer auch unabhängig von der Reihenfolge, in der die Member in der Struct-Typ-Deklaration angegeben werden.

Aggregat-Initialisierer können, wie Sie wahrscheinlich wissen, auch mit Arrays verwendet werden. Und C99 unterstützt auch die “getaggte” Initialisierung mit Arrays. Wie die “Tags” im Falle eines Arrays aussehen, zeigt das folgende Beispiel

int a[10] = { [5] = 3 };
/* `a[5]` is initialized with 3, the rest of `a` is zero-initialized */

Es ist noch einmal erwähnenswert, dass die C-Sprache weiterhin an dem „Alles-oder-Nichts“-Ansatz zur Aggregatinitialisierung festhält: Wenn Sie einen expliziten Initialisierer für nur ein (oder mehrere) Mitglieder einer Struktur oder eines Arrays angeben, wird das gesamte Aggregat erhalten initialisiert, und die Member ohne explizite Initialisierer werden mit Null initialisiert.

  • Die getaggte Initialisierung wird in C++ jedoch nicht unterstützt. Es wird nur der Sequenzstil unterstützt.

    – Shital Shah

    23. September 2016 um 6:34 Uhr

  • @AnT +1 für die tolle Antwort.

    – Guy Avraham

    16. Oktober 2017 um 11:03 Uhr

  • @Thomas: Du erfindest etwas. In VS2019 funktioniert es einwandfrei.

    – AnT steht zu Russland

    18. März 2020 um 8:05 Uhr

Sie verwenden die Namen der Mitglieder der Struktur, um die Struktur zu initialisieren. dh jede Mitgliedsinitialisierung wird mit dem Namen dieses Mitglieds “markiert”.

Ein weiterer erwähnenswerter Vorteil in Bezug auf diese Art der Initialisierung besteht darin, dass sie die Neuordnung von Strukturelementen ermöglicht, was in einigen Fällen Leistungsverbesserungen bewirken kann, indem beispielsweise Zeiger auf Elemente, auf die häufig zugegriffen wird, in derselben Hardware-Cache-Zeile platziert werden.

  • Es ist eine sehr wichtige Aussage (wenn sie wahr ist). Würde es nicht die Verwendung von verderben container_ofzum Beispiel?

    – LRDPRDX

    6. April 2020 um 17:09 Uhr

  • @LPDRDX Ich glaube, die Referenz bezieht sich auf die Neuordnung zur Kompilierzeit, nicht zur Laufzeit. container_of wird im Linux-Kernel verwendet, selbst wenn __randomize_layout für Strukturen verwendet wird.

    – Tim Vogel

    18. Juni 2020 um 22:24 Uhr

1408040cookie-checkWas ist die Initialisierungssyntax für markierte Strukturen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy