Ich habe gelesen, dass der sizeof-Operator in C zur Kompilierzeit interpretiert wird, und da der Compiler zur Kompilierzeit die Arraygröße und ihren Typ kennt, kann sizeof die Anzahl der vom Array belegten Bytes berechnen. Aber wie funktioniert sizeof für den folgenden Code:
#include<stdio.h>
#include<string.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int s=sizeof(a);
printf("%d",s);
return 0;
}
Hier ist die Arraygröße zur Kompilierzeit nicht bekannt, wie funktioniert sie dann richtig?
mögliches Duplikat von Using sizeof mit einem dynamisch zugewiesenen Array
– Mattball
9. April 2012 um 19:06 Uhr
Arrays variabler Länge sind für sie eine Ausnahme, sizeof wird zur Laufzeit ausgewertet, nicht zur Kompilierzeit.
– Daniel Fischer
9. April 2012 um 19:06 Uhr
@ MДΓΓБДLL Nein, das ist ungefähr malloced Zeug, nicht über VLAs.
– Daniel Fischer
9. April 2012 um 19:07 Uhr
@MДΓΓБДLL: Ihr mögliches Duplikat hat es mit einer anderen Situation zu tun (malloc()kein VLA, Array variabler Länge).
– Jonathan Leffler
9. April 2012 um 19:07 Uhr
sizeof wird immer zur Kompilierzeit in C89 berechnet. Seit C99 und Arrays mit variabler Länge wird es zur Laufzeit berechnet, wenn ein Array mit variabler Länge Teil des Ausdrucks in ist sizeof Operand.
Gleiches gilt für die Auswertung der sizeof Operand: Er wird nicht in C89 ausgewertet, aber in C99, wenn der Operand vom Array-Typ variabler Länge ist, wird er ausgewertet. Zum Beispiel:
int n = 5;
sizeof (int [n++]);
// n is now 6
Was bedeutet das int [n++]? Zum ersten Mal sehe ich es in C-Sprache
– Die Maske
9. Juni 2013 um 21:45 Uhr
@Die Maske int [N] ist ein Name vom Typ C. Es ist ein Array N von int. Wann N ist keine Konstante wie in der Antwort, es ist a Array mit variabler Länge.
– au
9. Juni 2013 um 21:49 Uhr
@ouah: Wir haben früher untersucht, dass der Ausdruck innerhalb des sizeof-Operators nicht wirklich ausgewertet wird. dh. sizeof(n++) lässt n auf 5 (wenn n=5 anfänglich). Warum wird dann hier der Wert von n geändert?
– rforritz
12. Juni 2013 um 21:27 Uhr
@rforritz Array-Typ-Operand mit variabler Länge ist eine Ausnahme von dieser Regel, in diesem Fall wird der Operand ausgewertet
– au
12. Juni 2013 um 21:33 Uhr
zwöl
Da Sie sich bewerben sizeof zu einem Array variabler Länge, dessen Größe zur Kompilierzeit nicht vollständig bekannt ist, muss der Compiler Code generieren, um einen Teil davon zur Laufzeit auszuführen.
Die High-Level-Optimierer von gcc 4.6.3 konvertieren den von Ihnen angezeigten Code
Erklärt das, was unter der Haube vor sich geht? (Lassen Sie sich nicht von der albern aussehenden Anzahl temporärer Variablen abschrecken – das ist ein Artefakt des Programms, in dem es sich befindet statische Einzelzuweisung Formular an der Stelle, an der ich um einen Zwischencode-Dump gebeten habe.)
Legen Sie die Datei, die Sie kompilieren möchten, in einem eigenen Verzeichnis ab, rufen Sie dann gcc von einer Shell in diesem Verzeichnis aus auf und fügen Sie hinzu -fdump-tree-all zu den Befehlszeilenoptionen (Sie möchten wahrscheinlich -S und -O2 auch). Sie müssen die Datei in einem Scratch-Verzeichnis isolieren, da dadurch etwa 100 Dateien mit Zwischencode generiert werden (und das ist nur die erste Hälfte der Optimierungspipeline; -fdump-rtl-all erhalten Sie weitere 60 Dateien). Sie können sie dann der Reihe nach durchlesen (sie sind nummeriert)
– zol
19. Juni 2013 um 3:02 Uhr
@TheMask (Fortsetzung) Die “Baum”-Dumps sind im Allgemeinen nützlicher als die “rtl”-Dumps, es sei denn, Sie versuchen, eines der “Backends” von GCC (Codegenerierung für eine bestimmte Architektur) zu debuggen. Sie können die Ausgabe auf einen bestimmten interessanten Durchgang beschränken, indem Sie sagen -fdump-(tree|rtl)-PASSNAME Anstatt von -all, wobei PASSNAME das Wort nach der Zahl im Dump-Dateinamen ist. Sehen gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/… (etwas nach oben scrollen, dann von dort bis zum Ende des Dokuments lesen) für weitere Details.
– zol
19. Juni 2013 um 3:07 Uhr
@TheMask … Ich sollte dich wahrscheinlich auch auf das hinweisen Interna-Handbuch für GCC was erklärt, was die Zwischendarstellungen sind und wie sie funktionieren.
– zol
19. Juni 2013 um 3:09 Uhr
Ich danke dir sehr! Ich werde mir das alles ansehen. 🙂
Das sizeof Operator liefert die Größe (in Bytes) seines Operanden, der ein Ausdruck oder der Name eines Typs in Klammern sein kann. Die Größe wird durch den Typ des Operanden bestimmt. Das Ergebnis ist eine ganze Zahl. Wenn der Typ des Operanden ein Array-Typ mit variabler Länge ist, wird der Operand ausgewertet; Andernfalls wird der Operand nicht ausgewertet und das Ergebnis ist eine ganzzahlige Konstante.
Greg Hewgill
In diesem Fall, sizeof() wird zur Laufzeit ausgewertet. Der Compiler, weil er weiß, dass die Größe von a basiert auf dem Wert von n Generiert zum Zeitpunkt der Array-Deklaration Code, um den entsprechenden Wert von zu verwenden n um einen sinnvollen Wert zurückzugeben sizeof().
In C99 werden nicht alle Verwendungen von sizeof() kann zur Kompilierzeit vollständig ausgewertet und auf eine Laufzeitkonstante reduziert werden.
Ich habe gelesen, dass der sizeof-Operator in C zur Kompilierzeit interpretiert wird
sizeof wird in allen Fällen außer für VLAs zur Kompilierzeit bestimmt. Für ein VLA, sizeof wird zur Laufzeit ausgewertet.
Tatsächlich (C11): “Wenn der Typ des Operanden ein Array-Typ mit variabler Länge ist, wird der Operand ausgewertet; andernfalls wird der Operand nicht ausgewertet und das Ergebnis ist eine ganzzahlige Konstante.”
– pmor
22. November 2021 um 16:00 Uhr
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN
Egal ob sizeof wird zur Kompilierzeit oder zur Laufzeit berechnet (oder formaler ausgedrückt, ob das Ergebnis ein ganzzahliger konstanter Ausdruck ist), das Ergebnis von sizeof basiert rein auf der Art seiner Argumentation und keine versteckten Daten, die das Array mit variabler Länge selbst begleiten. Natürlich wann sizeof auf einen variabel modifizierten Typ angewendet wird, muss das generierte Programm diese Größe irgendwo verfolgen. Aber es könnte es einfach neu berechnen, wenn der Ausdruck einfach genug wäre und die Variablen, von denen er ursprünglich die Länge abgeleitet hat, sich nicht geändert haben können. Oder es könnte die Größe des Typs irgendwo speichern (im Wesentlichen in einer versteckten lokalen Variablen), aber dies wäre nicht auf sichtbare Weise mit dem VLA-Objekt verbunden (z. B. wenn Sie einen Zeiger auf das erste Element des VLA übergeben zu einer anderen Funktion, kann dieser Zeiger nicht verwendet werden, um die VLA-Länge wiederherzustellen).
Tatsächlich (C11): “Wenn der Typ des Operanden ein Array-Typ mit variabler Länge ist, wird der Operand ausgewertet; andernfalls wird der Operand nicht ausgewertet und das Ergebnis ist eine ganzzahlige Konstante.”
– pmor
22. November 2021 um 16:00 Uhr
13531600cookie-checkWie funktioniert sizeof(array) zur Laufzeit?yes
mögliches Duplikat von Using sizeof mit einem dynamisch zugewiesenen Array
– Mattball
9. April 2012 um 19:06 Uhr
Arrays variabler Länge sind für sie eine Ausnahme,
sizeof
wird zur Laufzeit ausgewertet, nicht zur Kompilierzeit.– Daniel Fischer
9. April 2012 um 19:06 Uhr
@ MДΓΓБДLL Nein, das ist ungefähr
malloc
ed Zeug, nicht über VLAs.– Daniel Fischer
9. April 2012 um 19:07 Uhr
@MДΓΓБДLL: Ihr mögliches Duplikat hat es mit einer anderen Situation zu tun (
malloc()
kein VLA, Array variabler Länge).– Jonathan Leffler
9. April 2012 um 19:07 Uhr