C++ array size dependent on function parameter causes compile errors

12,444

Solution 1

What you have found it one of the Gnu compiler's extensions to the C++ language. In this case, Visual C++ is completely correct. Arrays in C++ must be defined with a size that is a compile-time constant expression.

There was a feature added to C in the 1999 update to that language called variable length arrays, where this is legal. If you can find a C compiler that supports C99, which is not easy. But this feature is not part of standard C++, not is it going to be added in the next update to the C++ standard.

There are two solutions in C++. The first is to use a std::vector, the second is just to use operator new []:

char *a = new char [n];

While I was writing my answer, another one posted a suggestion to use _alloca. I would strongly recommend against that. You would just be exchanging one non-standard, non-portable method for another one just as compiler-specific.

Solution 2

Your method of allocating from the stack is a g++ extension. To do the equivalent under MSVC, you need to use _alloca:

char *a = (char *)_alloca(n);

Solution 3

You are using something that is not a standard. Actually it is standard C but not C++. How peculiar is that!

Explaining a bit more, run time sized stack arrays are not part of C++, but are part of C99, the latest standard for C. That´s why some compilers will get it, while others will not. I would recommend refrain from using it, to avoid compiler compatibility issues.

The alternate implementation of the functionality would be using new and delete, as posted by strager.

Solution 4

You can use new/delete to allocate/free memory on the heap. This is slower and possibly more error prone than using char[n], but it's not part of the C++ standard yet, sadly.

You can used boost's scoped array class for an exception-safe method for using new[]. delete[] is automatically called on a when it goes out of scope.

void f(int n) {
    boost::scoped_array<char> a(new char[n]);

    /* Code here. */
}

You can also use std::vector, and reserve() some bytes:

void f(int n) {
    std::vector<char> a;
    a.resize(n);

    /* Code here. */
}

If you do want to use char[n], compile as C99 code instead of C++ code.

If you absolutely must allocate data on the stack for some reason, use _alloca or _malloca/_freea, which are extensions provided by MSVC libs and such.

Solution 5

variable length array was introduced in C99. It is supported in gcc but not msvc. According to a person in MSVC team, Microsoft has no plan to support this feature in their c/C++ compiler. He suggested to use std::vector in those cases.

Note that C99 does not require that the array allocated on the stack. The compiler can allocate it on the heap. However, gcc does allocate the array on the stack.

Share:
12,444
Ildar Zaripov
Author by

Ildar Zaripov

Updated on June 03, 2022

Comments

  • Ildar Zaripov
    Ildar Zaripov about 2 years

    I have a simple function in which an array is declared with size depending on the parameter which is int.

        void f(int n){
            char a[n];
        };
    
        int main() {
            return 0;
        }
    

    This piece of code compiles fine on GNU C++, but not on MSVC 2005.

    I get the following compilation errors:

        .\main.cpp(4) : error C2057: expected constant expression
        .\main.cpp(4) : error C2466: cannot allocate an array of constant size 0
        .\main.cpp(4) : error C2133: 'a' : unknown size
    

    What can I do to correct this?

    (I'm interested in making this work with MSVC,without using new/delete)