Ich habe einen C- Code im Linux-Kernel getroffen:
static struct ctl_table ip_ct_sysctl_table[] = {
{
.procname = "ip_conntrack_max",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
// ...
{
.procname = "ip_conntrack_log_invalid",
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &log_invalid_proto_min,
.extra2 = &log_invalid_proto_max,
},
{ }
};
Hier endet ein Array von Strukturen mit { }
. Zu welchem Zweck wurde es hinzugefügt?
Etwas oberhalb dieses Codes befindet sich übrigens ein weiteres Array von Strukturen , jedoch ohne leere Klammern am Ende.
Wann sollte ich am Ende eines Arrays von Strukturen leere Klammern verwenden?
c
arrays
struct
linux-kernel
NK-Zelle
quelle
quelle
-pedantic
.Antworten:
Diese spezielle Änderung war Teil des sysctl-Netzes: Entfernen Sie nicht verwendeten binären sysctl-Code , der von Eric W. Biederman festgeschrieben wurde, und ändern Sie die Initialisierung des letzten Elements des
ip_ct_sysctl_table
Arrays von{0}
auf{}
(und führen Sie ähnliche Änderungen wie bei vielen anderen Array-Initialisierungen durch).Das
{0}
Muster scheint jedoch schon viel länger zu existieren, und beide{0}
oder die{}
endgültige Elementinitialisierung wird üblicherweise (im Linux-Quellcode) explizit als bezeichnetTerminating entry
, sodass es wahrscheinlich ein Muster ist, das das Konsumieren dieser Arrays ohne Kenntnis ihrer Länge ermöglicht. Verbrauch beenden, wenn der mit Null initialisierte Abschlusseintrag erreicht wird. ZB für die ähnlichen Arrays insound/aoa/fabrics/snd-aoa-fabric-layout.c
der Absicht der Nullinitialisierung wird sogar explizit in einem Kommentar erwähnt, zB:quelle
int arr[] = {}
( vorausgesetzt , wir verwenden die leere Initialisierer-Erweiterung GNU) zu einem leeren Array führen; dh die Größe desarr
Seins0
?{ initializer-list }
dann Initialisierungsliste:designation(opt) initializer
oderinitializer-list , designation(opt) initializer
Sie sind wahrscheinlich mit nullterminierten Zeichenfolgen vertraut.
ctl_table ip_ct_sysctl_table[]
ist ein nullterminiertes Array, dh der letzte Arrayeintrag hat alle null Mitglieder.quelle
procname
null odermaxlen
null ist.procname
könnte ein sein,char[100]
in welchem Fall es ist""
, nicht null. Aber sonst ja.Um es klar auszudrücken: Die "leeren Klammern '{}' am Ende eines Arrays von Strukturen" werden nicht benötigt , um die C-Syntaxanforderungen zu erfüllen.
Wenn Code einen Sentinel-Wert wünscht .
Manchmal ist es für das Programm nützlich , ein endgültiges Array-Element aller Nullen zu haben - sicherlich, um das Ende zu erkennen. Der Bedarf ergibt sich aus der Verwendung eines Arrays durch die Anwendung
ctl_table ip_ct_sysctl_table[]
, nicht aus einem C-Sprachbedarf.quelle
Es ist ein mit Null initialisiertes Element am Ende des Arrays, um die Anzahl der Elemente des Arrays um eins zu erhöhen.
Betrachten Sie diese kleine Demo:
Die Größe des
arr
Arrays ändert sich, wenn Sie das{}
am Ende der Array-Initialisierungsliste auskommentieren.Ausgänge:
Mit
// {}
(Array hat 2 Elemente)Mit
{}
(Array hat 3 Elemente)Weitere Erklärung:
Das
ip_ct_sysctl_table
Array wird nur an einer Stelle verwendet, also hier:Das Extra
{}
erhöht die Gesamtgrößeip_ct_sysctl_table
.quelle
{ }
es sich um einen Initialisierer handelt. Aber das Warum ist noch unklar. So kann jetzt sowieso, das Wort wahrscheinlich ist wahrscheinlich eine gute Idee. :)