简体   繁体   中英

Ambiguous compiling of string array with non-constant size?

My gcc compiler from mingw64 8.1.0 doesn't allow the following to be compiled because var has to be a constant value:

    int var=3;
    string str[var];

int main(){

However, doing the same within main() doesn't show any errors:

int main(){
    int var;
    cin >> var;
    string str[var];

Why is there an ambiguity?

My compile command is simple: g++ main.cpp

These are the headers I had included in the beginning for both the cases:

#include <iostream>
#include <string>
#include <sstream>

Depending on your compile flags, they're both "wrong":

Code:

#include <string>

int i = 3;
std::string s1[i];

int main ()
{
  int j = 3;
  std::string s2[j];
  return 0;
}

g++ -o tmp3 -g -pedantic -Wall tmp3.cpp

tmp3.cpp:4:17: error: array bound is not an integer constant before ‘]’ token
 std::string s1[i];
                 ^
tmp3.cpp: In function ‘int main()’:
tmp3.cpp:9:19: warning: ISO C++ forbids variable length array ‘s2’ [-Wvla]
   std::string s2[j];

Remembering that VLAs are a 'C' feature ("discouraged" in C++, only supported as an "extension"), here are the rules:

https://en.cppreference.com/w/c/language/array

Declarator for VLA of unspecified size (can appear in function prototype scope only) where expression

  • any expression other than comma operator, designates the number of elements in the array qualifiers

  • any combination of const, restrict, or volatile qualifiers, only allowed in function parameter lists; this qualifies the pointer type to which this array parameter is transformed

Importantly:

Objects of any variably-modified type may only be declared at block scope or function prototype scope.

This is precisely why the first example is an "error"; the second a "warning". VLAs must be stack-allocated variables.

However, doing the same within main() doesn't show any errors

It would tell that this code is not correct C++ if you call it properly:

g++ -Wpedantic t.cpp

produces this warning:

t.cpp: In function ‘int main()’:
t.cpp:3:16: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
     int arr[var];

for this t.cpp file:

int main(){
    int var = 3;
    int arr[var];
}

GCC accepts Variable Length Arrays (VLAs) as a language extension, but only in certain situations (emphasis mine):

These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits

As an extension, GCC accepts variable-length arrays as a member of a structure or a union .

You can also use variable-length arrays as arguments to functions :

Creating an array outside of block scope (ie in global memory area) is not one of the accepted use-cases for VLA. See the documentation .

Note that, as everyone else mentioned, VLAs are GCC extension and are not a part of C++ standard. MSVC for example will not compile them at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM