2

I am slowly bringing myself up to c++11. I was looking at constexpr and stumbled into this wikipedia article which lead me to "something completely different". The basic example it gives is:

int get_five() {return 5;}
int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++

It states "This was not legal in C++03, because get_five() + 7 is not a constant expression." and says that adding constexpr to the get_five() declaration solves the problem.

My question is "What problem?". I compiled that code with neither errors nor warnings. I played with it making it horribly non constant:

#include <iostream>

int size(int x) { return x; }

int main()
{
  int v[size(5) + 5];
  std::cout << sizeof(v) + 2 << std::endl;
}

This compiles with no complaints using:

g++ -Wall -std=c++03

and when executed I get the (correct) answer 42.

I admit that I generally use stl containers, not arrays. But I thought (and apparently so did wikipedia) that compilation of the above code would fail miserably. Why did it succeed?

rpsml
  • 1,486
  • 14
  • 21
  • 5
    "What problem"? It is not legal C++. Your compiler is using a non-standard extension. Use the `-pedantic` flag. – juanchopanza Jan 06 '15 at 14:26
  • 3
    Variable length arrays(*VLA*) are C99 feature but many compilers [support it in C++ as an etension](http://stackoverflow.com/q/21273829/1708801) (*possible duplicate*) using the `-pedantic` flag will generate a warning and you can make it an error using `-pedantic-errors` – Shafik Yaghmour Jan 06 '15 at 14:26

3 Answers3

6

Variable-length arrays (that is, arrays whose size is determined by a non-constant expression) are allowed in C, and some C++ compilers allow them as an extension to the language. GCC is one such compiler.

You'll get a warning if you compile with -pedantic or -Wvla, or an error with -pedantic-errors. Use those flags if you want to avoid non-standard compiler extensions.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2

As it has been said already some C++ compilers support C feature named Variable Length Array(s) whose sizes can be specified at run-time.

However VLA(s) may not be declared with static storage duration. The program you showed

#include <iostream>

int size(int x) { return x; }

int main() 
{
    int v[size(5) + 5];
    std::cout << sizeof(v) + 2 << std::endl;

    return 0;
}

can be compiled. However if you place the array outside any function then the code will not be compiled. Consider the following program that is similar to your original program with minor changes.

#include <iostream>

int size(int x) { return x; }

int v[size(5) + 5];

int main() 
{
    std::cout << sizeof(v) + 2 << std::endl;

    return 0;
}

In this case the compiler will issue an error. However if you will specify constexpr for function size then the above program will be compiled successfully

#include <iostream>

constexpr int size(int x) { return x; }

int v[size(5) + 5];

int main() 
{
    std::cout << sizeof(v) + 2 << std::endl;

    return 0;
}

The C++ Standard requires that sizes of arrays would be constant expressions.

8.3.4 Arrays [dcl.array]

1 In a declaration T D where D has the form

D1 [ constant-expressionopt] attribute-specifier-seqopt

and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is an array type;

Take into acount that not all C++ compilers (and even C compilers; for C compilers it is implementation defined whether a compiler supports VLA) have such a language extension as VLA. So if you want that your program would be C++ compliant then you should not rely on specific language extensions of a compiler.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Some compilers have extensions, which implement VLA (Variable Length Arrays).

Compile with -pedantic and you'll see the difference.

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187