0

I am curious as to how this code snippet compiles:

#include <iostream>

struct A {
    virtual unsigned size() = 0;
};

struct B : public A {
    unsigned size() {
        return 5;
    }
};

struct C : public A {
    unsigned size() {
        return 100;
    }
};

void foo(A* a) {
    unsigned myArr[a->size()];
    std::cout << myArr[10];
}

https://godbolt.org/z/3u6JkI

Shouldn't the compiler complain that a->size() is not a constant expression? It has no idea if it should allocate 5 or 100 spaces for the array. Also, looking at godbolt's disassembly, I cannot find where it actually sizes the array. Should I expect to see that?

Edit: Note that this question is not asking why this feature is not allowed, but rather why it compiles when it is expressly forbidden by ISO C++. Therefore, it is not a duplicate of questions similar to the former question.

RoboCop87
  • 825
  • 1
  • 8
  • 21
  • Change the compiler to msvc and you will get an error. – PaulMcKenzie Apr 08 '19 at 21:56
  • 2
    Yes it should, g++ strikes again. – john Apr 08 '19 at 21:56
  • 1
    My assembly is quite poor, but I suspect the array is being sized here `sub rsp, rax`. It's allocated by adjusting the stack pointer in other words. – john Apr 08 '19 at 21:59
  • @PaulMcKenzie yes you are right, msvc does in fact give me an error. I am confused as to why you marked my question as a duplicate though. The linked question asks why this is not allowed, my question points out that despite it not being allowed, it still works in gcc and clang and I wanted to know why. I contest that these are different questions and not duplicates. – RoboCop87 Apr 08 '19 at 22:04
  • Use the appropriate compiler flags in g++ and you will get the error. It is that g++ does **not** allow it if you use the correct compiler flags (I believe -pedantic -Wall). It is just that by default, g++ and other compilers have the "use VLA" switch set to "on". – PaulMcKenzie Apr 08 '19 at 22:05
  • @PaulMcKenzie if you write an answer with the contents of your last comment, I will happily mark it as correct, because that answers my question perfectly. I did not know that g++ and clang had a "use VLA" switch. – RoboCop87 Apr 08 '19 at 22:11
  • -pedantic -Werror does the trick! – RoboCop87 Apr 08 '19 at 22:13

1 Answers1

1

The reason the compiler doesn't complain is because gcc provides Variable Length Arrays as a non-standard compiler extension. If you add -Wpedantic, it'll give you a warning about using a->size() for the size of the array:

<source>: In function 'void foo(A*)':
<source>:20:29: warning: ISO C++ forbids variable length array 'myArr' [-Wvla]
     unsigned myArr[a->size()];
                             ^

https://godbolt.org/z/BE-rfJ

Alecto Irene Perez
  • 10,321
  • 23
  • 46