3

I have started learning c++. I read that an array's size can only be set before run and dymanic arrays can be set during runtime. So I was expecting this to fail but it didn't:

#include <iostream>

int main() {
    using namespace std;
    int size;
    cout << "enter array size:";
    cin >> size;
    int i, score[size], max; //array size set to variable doesn't fail
    cout << endl << "enter scores:\n";
    cin >> score[0];
    max = score[0];
    for (i = 1; i < size; i++)
    {
        cin >> score[i];
        if (score[i] > max)
    max = score[i];
    }
    cout << "the highest score is " << max << endl;
    return 0;
}

Is this a new feature in recent C++ compilers? Is it realising I need a dynamic array and creating that instead?

mega6382
  • 9,211
  • 17
  • 48
  • 69
Ashley
  • 568
  • 2
  • 14
  • 3
    It's a non-standard exception. Just don't. – Luchian Grigore Jul 30 '13 at 12:44
  • 1
    @LuchianGrigore so only some comilers support it. Therefore should be ignored. Thanks for your help – Ashley Jul 30 '13 at 12:46
  • @Ashley I have seen it working in GCC, but may not work with Visual Studio. It is not a standard. – Pranit Kothari Jul 30 '13 at 12:48
  • 1
    If you're using GCC, compile your code with `-pedantic-errors` and then face the wrath of the compiler. – Nawaz Jul 30 '13 at 12:50
  • @Nawaz "error: ISO C++ forbids variable-size array ‘score’" great tip! Many thanks from a beginner – Ashley Jul 30 '13 at 12:53
  • Also, on GCC, compile with `-std=c++98` or `-std=c++11`. This disallows non-standard extensions. – juanchopanza Jul 30 '13 at 12:53
  • Note that in C++14 a slightly different form of arrays with runtime size will be allowed. Other than fixing a couple of differences (`sizeof` is a runtime operation on VLAs, it is forbidden in C++14...) this will become standard in the near future. – David Rodríguez - dribeas Jul 30 '13 at 13:09
  • @juanchopanza You need to use `-pedantic` or `-pedantic-errors` to get a warning or error for using VLA, [example](http://coliru.stacked-crooked.com/view?id=3d4af75f6e271e8983ae9e88df2478e6-7f4bc2c90970fdf19c48ebf8cc2bae3f) – Shafik Yaghmour Jul 31 '13 at 14:37

3 Answers3

5

Probably you are using GCC compiler, it has an extension called Arrays of Variable Length.

std::vector is the real dynamic arrays in C++.

To select this standard in GCC, use the option -std=c++11; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).

billz
  • 44,644
  • 9
  • 83
  • 100
  • If you are using gcc and you don't want this to be allowed, I suggest using the `-pedantic-errors` command line flag. – BoBTFish Jul 30 '13 at 12:53
3

In all current and past standards, that code is ill-formed. Variable Length Arrays are a C99 feature not a C++ feature, although some compilers do provide it as an extension. In the upcoming standard (expected to be C++14, currently in the process of review) a similar feature by other name (and slightly different semantics) has been adopted, so expect this to become standard in the future.

Note that in general, that is, excluding arrays of runtime bound (as they are named in the upcoming standard), the size of the array is part of the static type of the object and known at compile time. In the case of VLAs or array of runtime bound, the size is not known at compile time and thus the type is somehow of a second class citizen among types. The implication is that you cannot use VLAs/ARB with templates (as code generation for the template depends on the type, which includes the size, which is unknown at compile time).

In the same way there are other limitations, sizeof is not a compile time operation for VLAs, and it is not even allowed for ARB, these form of arrays can only be used for objects with automatic storage duration (i.e. in the stack), you cannot take the address of the array (although you can take the address of the first member),...

Another important point to consider is that the standard does not guarantee that the memory for an ARB will be allocated on the stack, and allows implementations to call a global allocation function, although the intention is that compilers will catch up and provide the space from the stack.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
0

Be careful! Undefined integers are not guarenteed to be any value at all. Some compilers will default to 0, while others will use whatever garbage bits where already in memory. For this reason Visual Studio wouldn't even let me compile. Step through your code to see the allocated memory for score before you set the size variable. Likely size as it is compiled is a random integer from garbage memory, which means it can change every time you execute!

A C style array needs to know how much continuous memory to allocate. This allows for direct indexing, and other optimizations. As others have suggested, std::vector is what is the standard dynamic container in C++, which uses an array under the hood.

john.dennis
  • 56
  • 2
  • 7
  • _(Ignoring the non-standard array[size] initialisation)_ To be safe I should always define a variable to something to avoid a garbage value. `int size = 0;` And not rely on `cin >> size;` – Ashley Jul 30 '13 at 13:15
  • btw Visual Studio lets you use unitialized values, but issues a warning – spiritwolfform Jul 30 '13 at 13:21
  • In debug mode, Visual Studio sets all uninitialized values to 0 by default. It does not allow an array to be created of size 0. Errors C2057, C2466, and C2133. – john.dennis Jul 31 '13 at 12:52