8

I have been teaching myself programming for couple of years, and I was sure that if you need array declaration of a variable number you need to use malloc or new.

Today I found that this compiles under g++ version 4.4.4, without warnings or errors:

#include <iostream>
using namespace std;

int main()
{
    int size_array;
    cin >> size_array;
    int iTable[size_array];

    for(int i=0;i < size_array;i++)
        iTable[i]=i*i;
    for(int i=0;i < size_array;i++)
        cout << iTable[i] << endl;

    return 0;
}

Also it compiles completely fine if you are using gcc (after changing cout and cin with printf and scanf)

Under Visual Studio this code fails to compile since size_array is not constant.

When this was changed? This is a safe method?

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • C tag removed, as this code is not even remotely C. – Puppy Mar 21 '11 at 12:17
  • Possibly duplicate: http://stackoverflow.com/questions/2427336/why-cant-i-create-an-array-with-size-determined-by-a-global-variable – Mihran Hovsepyan Mar 21 '11 at 12:20
  • 1
    @DeadMG, Soltys notes that the question still applies if you use printf and scanf. The example is c++, the question is more general. – Tom Mar 21 '11 at 12:28

8 Answers8

12

This is a C99 feature - VLA - which is not a part of standard c++. You can use it if your compiler supports it and you don't require portability. If the compiler supports it, it's perfectly safe to use - but it's a bad habit using non-standard features.

Erik
  • 88,732
  • 13
  • 198
  • 189
  • safe even if I put a size_array++ in the loop? surely not? – Tom Mar 21 '11 at 12:22
  • 1
    @Tom: Yes, it is. You won't change the size of the array doing that, though. – Puppy Mar 21 '11 at 12:27
  • 2
    @Tom: Sure is. The stack for the VLA is allocated once and not changed, sizeof will provide the actual size. If you change the variable you use to indicate size of an array it doesn't matter whether it's VLA or not - it's a logic error. – Erik Mar 21 '11 at 12:27
  • @Erik: with C++0x being based on C99, do you know if they integrated VLA into C++0x or not ? A quick search through the standard did not yield anything useful. – Matthieu M. Mar 21 '11 at 12:46
  • @Matthieu M. OTOH, no they didn't. I seem to recall hearing a reason for it, but can't remember it now – Erik Mar 21 '11 at 12:47
  • @Matthiew M : VLAs are not part of C++0x. – Prasoon Saurav Mar 21 '11 at 12:51
  • @Matthieu M. I remember the argument now... it'd break the ability for sizeof to always be used in integral constant expressions. I doubt that's the only reason though - VLAs are pure evil IMNSHO :) – Erik Mar 21 '11 at 12:54
  • 1
    @Erik: I must admit I quite like them, though the implementation soon gets tricky, especially when you want VLA within objects :D It might also have to do with `vector` being part of the STL, so they may not have felt as compelled as in C. – Matthieu M. Mar 21 '11 at 12:55
5

This is a compiler extension of gcc, not standard.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

No thats not safe at all. It could corrupt your stack.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
2

See http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.20.

Simply put, in C99, this is called VLA and is part of the standard (correct me if I'm wrong) but in C++ this is not part of the standard. If you need this functionality use std:vector instead.

helpermethod
  • 59,493
  • 71
  • 188
  • 276
0

It's okay to use the feature if you are using c99.

You have to be very careful about the value of size. a large value will overflow your stack, and your process may go insane.

chenju
  • 69
  • 4
0

This depends if you are writing C or C++. I'll assume C as for c++ you would be better off using std::vector rather than an array.

In C it depends which versiuon you are using. If and only if you are using a C99 standard compiler then the array can take its size from a variable at run time as you do here otherwise the size must be defined at compile time. Visual Studio does not support the dynamic array - see MSDN

C++ uses the C89 standard so requires the size to be set at compile time.

So in your case you need to see what flags you passed to the compiler.

As noted by @Eric the code is C++ so the working compiler is using a non standard extention so for gnu I would add flags to enforce a standard e.g. -ansi or -std=c++98 and -pedantic

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
0

There is an extension of GCC mimicking C99 Variable Length Arrays. It's not standard C++.

However, even if you have this turned off, the posted code can compile. The standard does not require a diagnostic for this case: it's Undefined Behaviour, not an error.

In really obvious cases a compiler may choose to prevent you from writing this, but otherwise it is free to let you fail in peace.

Conclusion: don't be fooled by the compilation. It's still bad and wrong.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

You can get this functionality in C or C++ with alloca (_alloca on Windows). std::vector is NOT a substitute: it is allocated on the heap, with new, which calls malloc, which is potentially expensive.

There is a good reason why you might want to have an array whose length is determined at runtime allocated on the stack: it's really fast. Suppose you have loop that executes frequently but has an array that depends on something at runtime (say, the size of your canvas widget). You can't just hard-code a number: your program will crash when we all get 36" 300 dpi Retina-display monitors and pixels[2400] is no longer safe. But you don't want new, or your loop hits a malloc and gets slow.

Although, for large arrays, it might be better to have a std::vector that is static to the function an only gets resized (larger) when necessary since your stack has limited size.

(See http://msdn.microsoft.com/en-us/library/wb1s57t5(VS.71).aspx)

prewett
  • 1,587
  • 14
  • 19