Why is new int[n] valid when int array[n] is not?

前端 未结 9 2020
暗喜
暗喜 2020-12-31 02:00

For the following code:

foo(int n){
    int array[n];
}

I understand that this is invalid syntax and that it is invalid because the c++ sta

相关标签:
9条回答
  • 2020-12-31 02:39

    This is because the C++ language does not have the C feature introduced in C99 known as "variable length arrays" (VLA).

    C++ is lagging in adopting this C feature because the std::vector type from its library fulfills most of the requirements.

    Furthermore, the 2011 standard of C backpedaled and made VLA's an optional feature.

    VLA's, in a nutshell, allow you to use a run-time value to determine the size of a local array that is allocated in automatic storage:

    int func(int variable)
    {
       long array[variable]; // VLA feature
    
       // loop over array
    
       for (size_t i = 0; i < sizeof array / sizeof array[0]; i++) {
         // the above sizeof is also a VLA feature: it yields the dynamic
         // size of the array, and so is not a compile-time constant,
         // unlike other uses of sizeof!
       } 
    }
    

    VLA's existed in the GNU C dialect long before C99. In dialects of C without VLA's, array dimensions in a declaration must be constant expressions.

    Even in dialects of C with VLA's, only certain arrays can be VLA's. For instance static arrays cannot be, and neither can dynamic arrays (for instance arrays inside a structure, even if instances of that structure are allocated dynamically).

    In any case, since you're coding in C++, this is moot!

    Note that storage allocated with operator new are not the VLA feature. This is a special C++ syntax for dynamic allocation, which returns a pointer type, as you know:

    int *p = new int[variable];
    

    Unlike a VLA's, this object will persist until it is explicitly destroyed with delete [], and can be returned from the surrounding scope.

    0 讨论(0)
  • 2020-12-31 02:43

    Because it has different semantics:

    If n is a compile-time constant (unlike in your example):

    int array[n]; //valid iff n is compile-time constant, space known at compile-time
    

    But consider when n is a runtime value:

    int array[n]; //Cannot have a static array with a runtime value in C++
    int * array = new int[n]; //This works because it happens at run-time, 
                              // not at compile-time! Different semantics, similar syntax.
    

    In C99 you can have a runtime n for an array and space will be made in the stack at runtime. There are some proposals for similar extensions in C++, but none of them is into the standard yet.

    0 讨论(0)
  • 2020-12-31 02:49

    The one and only valid answer to your question is, because the standard says so.

    In contrast to C99, C++ never bothered to specify variable length arrays (VLAs), so the only way to get variably sized arrays is using dynamic allocation, with malloc, new or some other memory-manager.

    In fairness to C++, having runtime-sized stack-allocations slightly complicates stack-unwinding, which would also make exception-handling for the functions using the feature consequently more bothersome.

    Anyway, even if your compiler provides that C99-feature as an extension, it's a good idea to always keep a really tight rein on your stack-usage:
    There is no way to recover from blowing the stack-limit, and the error-case is simply left Undefined Behavior for a reason.

    The easiest way to simulate VLAs in C++, though without the performance-benefit of avoiding dynamic allocation (and the danger of blowing the limit):

    unique_ptr<T[]> array{new T[n]};
    
    0 讨论(0)
提交回复
热议问题