clang++ cannot initialize a variable of type 'int(*)[dim2]' with an rvalue of type 'int (*)[dim2]'

前端 未结 3 1389
南笙
南笙 2021-01-27 12:31

Why does the code

void fcn(int *twoDArrayPtr, const int dim1, const int dim2) {
    int (*array)[dim2] = reinterpret_cast(twoDArrayPtr);
}

         


        
相关标签:
3条回答
  • 2021-01-27 12:48

    You're trying to use C99's Variable Length Array(VLA) feature when you use dim2 as the array dimension in your cast. (gcc, for example does support this by extension: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html.)

    Good news, you can't do this now but you will be able to soon with the introduction of C++14's Runtime Sized Arrays.

    Pertainant quotes:

    Runtime-sized arrays offer the same syntax and performance of C99’s VLAs... Bear in mind that runtime-sized arrays aren’t precisely the same as C99’s VLAs. The C++14 feature is more restrained, which is just as well. Specifically, the following properties are excluded:

    • Runtime-sized multidimensional arrays
    • Modifications to the function declarator syntax
    • sizeof(a) being a runtime-evaluated expression returning the size of a
    • typedef int a[n]; evaluating n and passing it through the typedef

    So you're code will be legal soon, circa C++14.

    I've tried it out on the Visual Studio 2015 Beta and sadly at time of writing it is not supported :(

    0 讨论(0)
  • 2021-01-27 12:59

    Although clang does not support variable-length arrays, there is a workaround. The following compiles with clang++ 4.0.0:

    void fcn(int *twoDArrayPtr, const int dim1, const int dim2) {
        using array_type = int (*)[dim2];
        array_type array = reinterpret_cast<array_type>(twoDArrayPtr);
    }
    
    int main() {
        return 0;
    }
    

    I'm not sure why this alias declaration should make any difference. It certainly seems inconsistent.

    0 讨论(0)
  • 2021-01-27 13:01

    dim2 is not a compile-time constant, and VLAs (variable-length arrays) don't exist in C++. Some other compilers (such as gcc) have language extensions to allow VLAs in C++, but clang's behavior is standard-conforming.

    You can work around the problem with a class (or class template) that does the address translation for you, such as

    // This is very rudimentary, but it's a point to start.
    template<typename T>
    class array2d_ref {
      public:
        array2d_ref(T *p, std::size_t dim) : data_(p), dim_(dim) { }
    
        T *operator[](std::size_t i) { return &data_[i * dim_]; }
    
      private:
        T *data_;
        std::size_t dim_;
    };
    
    ...
    
    array2d_ref<int> array(twoDArrayPtr, dim2);
    

    But I'm afraid it is not possible (portably) to have a pointer-to-array unless you know the dimension of the array at compile time.

    0 讨论(0)
提交回复
热议问题