Warum sollte die globale Arraygröße eine Ganzzahlkonstante sein?

8

In C ++ habe ich versucht, ein globales Array mit einer bestimmten Größe zu deklarieren. Ich habe den Fehler bekommen:

Array gebunden ist keine Ganzzahlkonstante vor dem Token ']'

Aber wenn ich ein Array des gleichen Typs in der main()Funktion deklariert habe, funktioniert es einwandfrei.

Warum gibt es hier ein anderes Verhalten?

int y=5;
int arr[y];         //When I comment this line it works fine

int main()
{
    int x=5;
    int arr2[x];        // This line doesn't show any error.
}

Bearbeiten: Viele schlagen vor, dass diese Frage ein Duplikat des Abrufs des Fehlers "Array gebunden ist keine Ganzzahlkonstante vor ']' Token" ist . Diese Frage beantwortet jedoch nicht, warum es ein anderes Verhalten gibt.

Syed Maqthyar
quelle
3
Auch mainwenn es nicht legal ist, verwendet es die VLA-Erweiterung.
Jarod42
4
Die Grenzen aller Arrays in C ++ müssen einen Wert haben, der während der Kompilierung bekannt ist. Wenn ein solcher Code beim Einfügen mainvon Ihrem Compiler "akzeptiert" wird: Sie verwenden die Compiler-Erweiterung, mit der VLAs kompiliert werden können, auch wenn sie vom C ++ - Standard nicht unterstützt werden.
Algirdas Preidžius
2
Verwechseln Sie "keine Compilerfehler" nicht mit "funktioniert einwandfrei". In diesem Fall bedeutet "einwandfrei funktionieren", dass Ihr Code auf einer nicht vom Standard-Compiler bereitgestellten Erweiterung basiert, dh es ist in Ordnung, aber nicht portabel. C ++
idclev 463035818
Warum nicht deklarieren yund xals const? Müssen Sie den Wert von yoder ändern x? Hoffentlich nicht, denn das wirft viele Fragen darüber auf, wie groß arrund wie groß arr2sein sollte - insbesondere in Bezug auf die Initialisierungsreihenfolge. (Hinweis: Sie sollten Konstanten sein)
Wyck
Kompilieren Sie Ihr Programm mit --std=c++17(oder --std=c++11wenn es sich um einen älteren Compiler handelt), und die Kompilierung schlägt fehl.
Einpoklum

Antworten:

9

Beide Beispiele sind in C ++ schlecht ausgebildet. Wenn ein Compiler letzteres nicht diagnostiziert, entspricht er nicht dem Standard.

Warum gibt es hier ein anderes Verhalten?

Sie verwenden eine Spracherweiterung, die automatische Arrays zur Laufzeitlänge ermöglicht. Ermöglicht jedoch keine statischen Arrays zur Laufzeitlänge. Globale Arrays verfügen über statischen Speicher.

Wenn Sie GCC verwenden, können Sie es mithilfe der Befehlszeilenoption -pedantic auffordern, dem Standard zu entsprechen. Es ist eine gute Idee, dies zu tun, um über Portabilitätsprobleme informiert zu werden.

Eerorika
quelle
4

Die Größe eines Arrays muss konstant sein. Sie können dies beheben, indem Sie yals deklarieren const.

const int y=5;
int arr[y]; 

Aus Gründen, warum dies funktioniert mainhat, erlaubt g ++ ein Array variabler Länge im Blockbereich als Erweiterung. Es ist jedoch kein Standard-C ++.

dbush
quelle
0

Beide sollten nicht verwendet werden, man funktioniert, weil (wie @eerorika sagte) Arrays mit automatischer Länge zur Laufzeit zulässig sind, globale Arrays jedoch statischen Speicher benötigen.

Wenn Sie ein Array mit einer variablen Größe deklarieren möchten (z. B. angegeben durch std :: cin), würden Sie Folgendes tun:

int x;
std::cin >> x;
const int n = x;
float arr[n];

Sie können es jedoch nicht so einstellen, dass es nur Nullen enthält float arr[n] = {0}(wenn Sie einen Wert im Array hinzufügen müssen, ohne sicher zu sein, dass Sie ihn festgelegt haben), müssen Sie eine solche Schleife verwenden

for(int i = 0; i < n; i++)
{
    arr[i] = 0;
}
Jacob Korba
quelle
1
Ihr Beispiel ist trotz der Verwendung von const immer noch schlecht geformt. Die Größe muss ein konstanter Ausdruck für die Kompilierungszeit sein. Etwas, das Sie von der Laufzeiteingabe erhalten, erfüllt das natürlich nicht.
Eerorika
Die Aussage, dass „beide nicht verwendet werden sollten“, ist unangemessen. Man könnte vermeiden wollen, ein Array variabler Länge zu verwenden, um tragbaren C ++ - Code zu schreiben. Möglicherweise möchten Sie ein Array mit variabler Länge verwenden, um ein gewünschtes Projektziel auf Kosten der Portabilität zu erreichen. Die Werte dieser Ziele sind subjektiv und umständlich, und Sie können nicht sagen, wo das Gleichgewicht für eine andere Person liegt.
Eric Postpischil
@EricPostpischil Sie haben Recht, aber wenn Sie eine veränderbare Variable verwenden, können Sie sie ändern. Aus Sicherheitsgründen ist es besser, sie als Konstante beizubehalten
Jacob Korba
0

Das Typsystem von C ++ behandelt diese C-ähnlichen Arrays auf eine Weise, die es anhand arr2Ihres Typbeispiels definiert int[5]. Ja, die Anzahl der Elemente des Arrays ist Teil des Typs!

Dies legt einige Einschränkungen für das fest, was Sie bei der Definition von C-ähnlichen Arrays verwenden dürfen. Das heißt, diese Nummer muss statisch gespeichert sein , unveränderlich sein und zur Kompilierungszeit verfügbar sein .

Vielleicht möchten Sie Ihren Code in etwas wie das Folgende ändern, das einen weiteren Leckerbissen enthält. Das Array wird ordnungsgemäß initialisiert:

int arr2[] = {0, 0, 0, 0, 0};   
Salchint
quelle