Warum wird sizeof als Kompilierzeitoperator bezeichnet?

12

Dies ist ursprünglich ein Teil einer anderen Frage.

Warum wird sizeofein Operator zur Kompilierungszeit genannt? Ist es nicht tatsächlich ein Laufzeitoperator? Und wenn es sich in der Tat um einen Operator zur Kompilierungszeit handelt, wie kann er dazu beitragen, portablen Code zu erstellen, der auf verschiedenen Computern gleich ausgeführt wird? Bitte erläutern Sie im Detail.

Der friedliche Kodierer
quelle
4
ausführlich beantwortet bei SO: Warum erhöht sizeof (x ++) x nicht?
Mücke
3
Wie soll sich die Größe eines Typs zur Laufzeit ändern?
@MichaelT: Die Größe einer Instanz eines Typs kann sich sicherlich ändern - schließlich gibt es Klassenpolymorphismus. Ich würde behaupten, sizeof(polymorphic_ptr*)dass es ziemlich kontraintuitiv und einfach albern ist, konstant zu sein. Ja, es ist der C ++ - Weg, aber trotzdem albern.
Setzen Sie Monica am
@ KubaOber In der Tat. Ich bin nur neugierig, wie sich das OP in verschiedenen Fällen verhalten sollte, und hoffe, dass ich einen Code bekomme, der seine Verwirrung darüber demonstriert, um die Frage zu erweitern.
4
Kam, um die Antwort zu stimmen "weil es zur Kompilierungszeit arbeitet", links enttäuscht.
Ben Jackson

Antworten:

23

sizeof()gibt die Größe des Datentyps an , nicht die Größe einer bestimmten Instanz dieses Typs im Speicher.

Wenn Sie beispielsweise ein Zeichenfolgendatenobjekt hatten, das zur Laufzeit ein Zeichenarray mit variabler Größe zugewiesen hat, sizeof()konnte die Größe dieses Zeichenarrays nicht ermittelt werden. Es würde Ihnen nur die Größe des Zeigers geben.

Die Größe eines Datentyps ist beim Kompilieren immer bekannt.


quelle
3
Da C (++) keine Laufzeitobjekt-Metadaten hat, können Sie diese Dinge auch zur Laufzeit nicht wirklich abrufen.
C. Ross
5
Eigentlich, wenn Sie verwenden , sizeofauf einem Array, Sie werden die Größe des Arrays erhalten (die die Elementgröße multipliziert mit der Anzahl der Elemente). Wenn Sie es jedoch für einen Zeiger verwenden, erhalten Sie nur die Größe des Zeigers. Da Sie in den meisten Fällen, in denen Sie die Größe eines Arrays kennen möchten, nur einen Zeiger haben, ist dies nicht besonders nützlich.
SEPP2K
1
@Jens Die Frage ist mit [C ++] markiert und VLA hat es nicht in den C ++ - Standard geschafft.
Authchir
13

da die gesamte Größe von "call" zur Kompilierungszeit berechnet wird und alles, was sich zwischen den Klammern befindet, verworfen und nicht zur Laufzeit ausgeführt wird,

Das Ergebnis basiert ausschließlich auf statischen Typinformationen, die dem Compiler zur Verfügung stehen

Ratschenfreak
quelle
7

Warum wird sizeof als Kompilierzeitoperator bezeichnet?

Weil der Compiler zur Kompilierzeit die Größe des Ausdrucks berechnet und diesen konstanten Wert zur Kompilierzeit ersetzt.

Ist es nicht tatsächlich ein Laufzeitoperator?

Nein. Sie können sogar sizeofdie Größe von Ausdrücken auswerten, die Sie nicht legal ausführen können (dh die ein undefiniertes Verhalten verursachen würden), solange der Compiler den Typ des Ausdrucks ermitteln kann.

Darüber hinaus constexprkönnen Sie sizeofAusdrücke auch vor C ++ 11 so verwenden, dass Laufzeitausdrücke nicht verwendet werden können.

Und wenn es sich in der Tat um einen Operator zur Kompilierungszeit handelt, wie kann er bei der Erstellung von portablem Code helfen?

Die Typen können auf verschiedenen Plattformen unterschiedlich groß sein. Die Verwendung von sizeofAusdrücken anstelle von fest codierten Annahmen bedeutet, dass Ihr Code nicht beschädigt wird, wenn Sie auf einer anderen Plattform kompilieren und Ihre Typen die Größe ändern.

Nutzlos
quelle
1
Nun, ich finde das die nützlichste Antwort;). Bro (unter der Annahme, dass Sie männlich sind), ich habe Zweifel. Wollen Sie damit sagen, dass, wenn die Leute sagen, dass sizeof Programme portabel macht, der Quellcode auf allen Computern fehlerfrei kompiliert werden kann und das ausführbare Programm nicht auf jedem Computer ausgeführt werden kann? Richtig ? Wenn dies richtig ist, wird mein Zweifel wirklich geklärt.
The Peaceful Coder
1
Ja, der Code ist portabel, in dem Sinne, dass Sie für jede Plattform eine (andere) korrekte Binärdatei kompilieren können.
Nutzlos
5

C ++ speichert die Metadaten für Objekte nicht zur Laufzeit, daher muss die Größenprüfung zur Kompilierungszeit erfolgen. Deklarieren Sie für ein Beispiel, wie C ++ Größe nicht überprüft, ein Array von intbeliebiger Größe und lesen Sie über das Ende davon hinaus. Wenn Sie Glück haben, werden Sie segfaultwahrscheinlich nur Kauderwelsch lesen, da C ++ die Größe Ihres Arrays nicht nachverfolgt.

Siehe Kann ein C / C ++ - Programm das Lesen nach dem Ende eines Arrays (UNIX) verhindern? für ein Beispiel aus SO.

Kreuz
quelle