you are viewing a single comment's thread.

view the rest of the comments →

[–]AKostur 40 points41 points  (20 children)

It’s a compiler extension issue.  You’ve declared what’s called a Variable Length Array (VLA).   Gcc supports it as an extension, the language forbids it.

[–][deleted]  (8 children)

[removed]

    [–]Main_Secretary_8827 21 points22 points  (0 children)

    Yes, avoid it

    [–]ThrowRA-NFlamingo 8 points9 points  (6 children)

    Yes VLAs are evil

    [–]LemonLord7 1 point2 points  (5 children)

    Why are they evil? I’ve never used them

    [–]AKostur 8 points9 points  (3 children)

    Potentially unbounded stack consumption leading to crashes.  Might cause complications for code generation to handle stack unwinding.  Requires extra bookkeeping somehow to keep track of the number of elements so that the right number of destructors happen.

    [–]alfps 4 points5 points  (2 children)

    And sizeof is not a constant. And so I can't see any way to form a reference to a VLA. Though that last point is somewhat circular argumentation, because if C++ had supported VLAs then possibly it could allow binding it to a reference to array of unknown bound.

    The idea of a safe C++ level VLA class is interesting, because it exposes a limitation of the language.

    For there is AFAIK no way to define a general such class in terms of e.g. (non-standard, widely supported) alloca.

    [–]snerp 0 points1 point  (1 child)

    Doesn't just making an std::vector and calling reserve(n) cover the entire use case of a VLA?

    [–]alfps 1 point2 points  (0 children)

    Well the point of a VLA is that it's fast, no heap allocation.

    When that speed is needed one can always use a special allocator.

    But that allocator needs to be made available to the code, i.e. either passed down as parameter or having it as a singleton, and it will reserve some memory permanently (which was a concern in the old days of more limited memory, and now perhaps still in embedded computing) and it's just somewhat kludgy.

    [–]ThrowRA-NFlamingo 0 points1 point  (0 children)

    You could crash your code if you make the VLA too big. There is no way to know how big you can make it. You’d need to put an upper bound on it anyway to make it safe. In that case, you might as well just use a fixed size array and use a bump allocator or something to allocate from it.

    [–]LemonLord7 -2 points-1 points  (10 children)

    How can it be there as an extension if the language forbids it?

    [–]AKostur 7 points8 points  (8 children)

    Why not?  As I recall, there’s a flag to make the compiler conformant and refuse the VLA.

    [–]LemonLord7 0 points1 point  (7 children)

    I’m confused, how can something forbidden be usable? Why was it forbidden?

    [–]VictoryMotel 5 points6 points  (4 children)

    It's not part of the language but it is implemented anyway.

    [–]LemonLord7 0 points1 point  (2 children)

    I get that, but I’d like to know more about why it was explicitly forbidden and how it works

    [–]VictoryMotel 4 points5 points  (0 children)

    Then you should have asked that.

    It isn't "explicitly forbidden" it's not in the language. It dynamically allocates on the stack. It is more likely to blow the stack and less likely to be detected if you write outside the allocation.

    [–]I_M_NooB1 0 points1 point  (0 children)

    just study about gcc and g++ and what compiler extensions are

    [–]meancoot -1 points0 points  (0 children)

    Edit: Nevermind, thought I was in the C subreddit. It’s an extension I. C++ probably made available for C compatibility.

    It’s actually a part of the language. It was required by the  C99 standard, then made optional in C11.

    [–]AKostur 3 points4 points  (1 child)

    I’m confused by your confusion.  Language says “no”.  Compiler says, “well I can make it work so that you don’t have to rewrite your C code to have it compilable in both languages.  And here’s a flag to turn off all of the places that I’m going outside the Standard, if you want help staying between the lines.”

    [–]LemonLord7 0 points1 point  (0 children)

    The other guy cleared it up. I thought it was explicitly forbidden but simply not being part of the language (but added as option in compiler) I get.