2015-08-25 8 views
9

Ich hatte den Eindruck, dass Array-Deklarationen variabler Größe in C89 nicht möglich waren. Aber, wenn sie mit clang -ansi Kompilieren Ich kann den folgenden Code auszuführen:Mit sizeof() in Array-Deklarationen in C89

double array[] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; 
double other_array[sizeof(array)] = { 0.0 }; 

Was ist hier los? Wird dies nicht als Array-Deklaration variabler Größe betrachtet?

+0

whaoppps, editied –

+1

Es gibt keine variable Größe Arrays in C89 ist, so könnte es nicht in Betracht gezogen werden Array-Deklaration variabler Größe. . –

Antwort

5

Das liegt daran, dass aufgrund des sizeof Operators ist konstanter Ausdruck, so dass es nicht für VLA qualifiziert, ebenso wie die folgenden Erklärung ab:

int other_array[5]; 

kann auch nicht-Array mit variabler Länge sein. Von C11 (N1570) §6.6/p6 Konstante Ausdrücke (Hervorhebung von mir für die Zukunft):

Eine Integer-Konstante Ausdruck117) werden Integer-Typ haben und soll nur Operanden, die ganzzahlige Konstanten sind , Enumerationskonstanten, Zeichenkonstanten, sizeof Ausdrücke deren Ergebnisse sind ganzzahlige Konstanten , _Alignof Ausdrücke und schwimmenden Konstanten, die die Direktoperanden von Abgüssen sind.

Der Vollständigkeit halber, die sizeof Betreiber über führen nicht immer in konstanten Ausdruck, obwohl dies nur post-C89-Standards betrifft (in C11 VLAs optional gemacht wurden). Unter Bezugnahme auf § 6.5.3.4/p2 Die sizeof und _Alignof Operatoren:

Wenn der Typ des Operanden mit variabler Länge Array-Typ ist, der Operand wird ausgewertet; Andernfalls wird der Operand nicht ausgewertet und das Ergebnis ist eine Ganzzahlkonstante.

3

Zuerst sehen wir die Kriterien für ein Array (nicht) ein VLA. C11 doc, Kapitel §6.7.6.2,

[...] Wenn die Größe eine ganze Zahl konstanter Ausdruck und der Elementtyp eine bekannte konstante Größe hat, die Art Array ist kein variabler Länge Array-Typ ; [...]

zu Ihrem Fall kommt, ist sizeof ein Compiler-Operator, so erzeugt es einen Wert, die Kompilierung konstanten Ausdruck betrachtet wird. Eine Array-Definition, deren Größe als Kompilierzeitkonstantenausdruck angegeben wird, ist kein VLA. Also, in Ihrem Code,

int other_array[sizeof(array)] 

ist kein VLA.

Bezüglich des sizeof Operator Ergebnis von C11, Kapitel §6.5.3.4, (emphasis Mine)

sizeof Der Operator liefert die Größe (in Bytes) des Operanden, der ein Ausdruck sein kann, oder der eingeklammerte Name eines Typs. [...] ansonsten wird der Operand nicht ausgewertet und das Ergebnis ist eine Integer-Konstante.

+2

In C11 ist 'sizeof' kein" Kompilieroperator "und erzeugt manchmal keinen konstanten Ausdruck. (Obwohl OP nach C89 gefragt hat) –

8

In ANSI C89 a.k.a. ISO C90, die sizeof Operator ergibt sich eine ganzzahlige Konstante , die für die Array-Dimensionen geeignet ist. Funktionsaufrufe zum Beispiel sind nicht.

Ich möchte eine weitere Bemerkung hinzufügen, da ich glaube, dass der Code, wie er ist, ein Problem hat, das übersehen werden könnte.

Wenn die other_array als

erklärt
double other_array[sizeof(array)]; 

es wird weder die gleiche Anzahl von Elementen haben, noch die gleiche Größe (das nur wahr wäre für Array von char) als array[]. Wenn es die Absicht, ein zweites Feld mit der gleichen Anzahl von Elementen (unabhängig vom Typ) zu erklären ist, verwenden:

double other_array[sizeof(array)/sizeof(*array)]; 
+1

Warum der Downvote? – Jens

+3

Nicht mein Downvote, aber das ist keine Antwort auf die Frage. Dies sollte ein Kommentar sein. –

+0

@JensGustedt Fair genug. Aber ich habe versucht * wirklich * zu verstehen, was der Code erreichen sollte, sehe mehr als die technische Frage, finde heraus, warum jemand ein anderes Array möchte, die Anzahl der Elemente war eins für jedes Byte in einem doppelten Array. Das sieht nicht gut aus und die Kommentare sind einfach zu begrenzt, wenn es um die Formatierung geht. Vielleicht sollte ich die technische Antwort ein drittes Mal wiederholen, um der Antwort Erwartung zu entsprechen. – Jens