Ich habe zwei Arten der Verwendung sizeof
für speicherbezogene Vorgänge gesehen (z. B. in memset
oder malloc
):
sizeof(type)
, undsizeof variable
odersizeof(variable)
Welchen würden Sie bevorzugen, oder würden Sie eine Mischung der beiden Stile verwenden, und wann würden Sie jeden Stil verwenden? Was sind die Vor- und Nachteile eines jeden Stils und wann benutzt du sie?
Als Beispiel kann ich die folgenden Situationen sehen, in denen ein Stil hilft und der andere nicht:
Wenn Sie die falsche Zeiger-Indirektion erhalten:
type *var;
...
memset(var, 0, sizeof var); /* oops */
Wenn sich der Typ ändert:
new_type var; /* changed from old_type to new_type */
...
memset(&var, 0, sizeof(old_type)); /* oops */
quelle
array
es sich in der Tat um ein C-Array handelt, wirdsizeof(array)
die Anzahl der zum Speichern der Array-Elemente erforderlichen Bytes zurückgegeben . Wennarray
es sich um einen Zeiger auf das erste Element eines zerfallenen C-Arrays handelt, gilt Ihre Anweisung. Wenn Sie ein C-Array als Funktionsargument übergeben, sieht es wie ein Zeiger in der Funktion aus. Alle Informationen, die beweisen, dass es sich um ein Array handelt, gehen ebenso wie die Größe verloren. Deshalb ist es verfallen . Falsch 2: "Arrays existieren in C eigentlich nicht; ... einfach syntaktischer Zucker für Zeiger."Es ist (wie immer) vorzuziehen, Ihre Absicht so direkt wie möglich wiederzugeben.
Ist die Absicht, gegen den Speicher einer vorhandenen Variablen zu arbeiten? Wenn ja, verwenden Sie
sizeof(variable)
, da dies so genau wie möglich zeigt, dass Sie sich um den Speicher der Variablen selbst kümmern.Soll der Typ berechnet werden, um beispielsweise zu bestimmen, wie viel Speicher für eine neue Instanz reserviert werden soll? Wenn ja, dann benutze
sizeof(type)
.Das heißt, ich bevorzuge
Über
wie die letzteren Fall aussieht wie Sie versuchen , eine Variable zuzugreifen, die noch nicht existiert.
Andererseits bevorzuge ich
Über
da die Absicht eindeutig darin besteht, den Inhalt der Variablen auf Null zu setzen, ist dies die Variable, gegen die wir vorgehen sollten. Der Versuch, die Typ-Metadaten zu verwenden, verwirrt hier nur die Dinge.
quelle
void *
automatische Casting auf andere Zeigertypen für eine Fehlfunktion.Ich würde es vorziehen , in beträchtlichem Ausmaß
sizeof(type)
übersizeof variable
. Auch wenn Sie sich mehr Gedanken über den Typ machen und weitere Änderungen vornehmen müssen, können Sie Zeiger-Indirektionsfehler vermeiden, die zu den häufigsten Fehlerursachen in C gehören .Ich würde mich nicht so sehr um Bugs kümmern, bei denen der Typ
sizeof(type)
geändert wird. Wenn Sie den Typ einer Variablen ändern, sollten Sie einen schnellen Scan durchführen, um festzustellen, wo diese Variable verwendet wird und ob Siesizeof(type)
Anweisungen ändern müssen . Obwohl es immer die Möglichkeit gibt, dies falsch zu verstehen, besteht ein viel geringeres Risiko als bei Zeiger-Indirektionsfehlern.Ein Vorteil von
sizeof variable
ist für Arrays, aber in der Praxis habe ich festgestellt, dass das Übergeben von Arrays als Paare von first / len viel häufiger vorkommt (in diesem Fall wird nur die Länge verwendet) Array / Pointer-Zerfall, wie in diesem Beispiel:quelle
sizeof var
; Wenn es ein Zeiger ist, ist essizeof *var
. Dies ist auch etwas, was die Leute falsch machen können, und der Compiler wird es gerne ohne Beschwerde annehmen. Ich behaupte, dass diese Fehler viel schwerer zu erkennen und häufiger sind als Fehler mit dersizeof(type)
Form.C
, ist das Posten von C-Code informativer als C ++ - Codemat3_t::mat3_t(...)
.Ziel ist es, Redundanz zu beseitigen. Wenn Sie sizeof für eine Operation verwenden, die sich auf eine Variable bezieht, müssen Sie dies natürlich in sizeof widerspiegeln. Ja, Sie können es wie im ersten Beispiel vermasseln, aber die Heilung ist nicht vom Typ, sondern vom Typ * var, der korrekt zum Ziel passt.
Um solche Probleme abzumildern, ist es üblich, Makros, Vorlagen und ähnliche Tools zu verwenden, die für den Anwendungsfall geschult sind, und nicht nackte Größe.
Siehe mein CLEAR-Makro , das ausschließlich anstelle des nackten Memset verwendet wird. Ich habe meinen Arsch mehrmals gerettet, wenn ein Tippfehler aufgetreten ist oder wenn ein Strukturinhalt einen Vektor oder eine Zeichenfolge gefunden hat ...
quelle
Geschäftslogik definiert Ihre Wahl.
Wenn sich Ihr Code auf eine bestimmte Variable bezieht und diese Variable fehlt, ist Ihr Code nicht sinnvoll - wählen Sie
sizeof(var)
Wenn Sie Code für eine Reihe von Variablen mit einem bestimmten Typ verwenden, wählen Sie
sizeof(type)
. Normalerweise benötigen Sie dies, wenn Sie eine haben,typedef
die viele Variablen definiert, die Sie je nach Typ unterschiedlich verarbeiten (z. B. Serialisierung). Möglicherweise wissen Sie nicht, welche dieser Variablen in zukünftigen Codeversionen verbleibt. Daher ist es logisch richtig, Typ als Argument auszuwählen. Sogar das Ändern von solchemtypedef
wird Ihre Größe der Linie nicht beeinflussen.quelle
Je nach Verwendungszweck könnte sizeof (variabel) die beste Lösung sein. Auf diese Weise können Sie Ihren Variablentyp bei Bedarf ändern, ohne alle Einträge für den Typ zu korrigieren. Aber auch hier kommt es auf Ihr Ziel an.
quelle