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

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

Why does the code

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

generate the compiler error

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

The types are the same, so I'd think the assignment can be performed. Since int (*)[dim2] is a pointer to an array of size dim2 and as such could be a pointer to a bunch of arrays of size dim2 in contiguous memory indexable by the pointer, I would think this should work.

I'm using clang++ on Mac OS/X with the following version information:

Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.0.0 Thread model: posix 

回答1:

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.



回答2:

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 :(



回答3:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!