0

I have a function which gets a pointer to a C-style array. When I explicitly set the type of the variable twoDArray and then compile the code with Clang I get the following error:

main.cpp:8: error: variable-sized object may not be initialized
const T (&twoDArray)[dim1][dim2]{*reinterpret_cast<const T (*)[dim1][dim2]>(cVector)};

When I comment out the line and use the commented out part the code will compile correctly. When I use g++ to compile the code both variants will be accepted.

Is this an error in the Clang compiler, or does g++ accept some code in this case which is non standard?

#include <iostream>

using namespace std;

void printVector(const double *cVector, const size_t dim1, const size_t dim2)
{
    const double (&threeDArray)[dim1][dim2]{*reinterpret_cast<const double (*)[dim1][dim2]>(cVector)};
//    auto threeDArray{*reinterpret_cast<const double (*)[dim1][dim2]>(cVector)};
}

int main()
{
    const size_t VEC_SIZE{2};
    double cVector[VEC_SIZE][VEC_SIZE]{{1.1, 2.2}, {3.3, 4.4}};
    size_t vecSize{VEC_SIZE};
    printVector(&cVector[0][0], vecSize, vecSize);
    return 0;
}
Martin Stolpe
  • 135
  • 1
  • 6
  • One major issue is that C++ doesn't have [variable-length arrays](https://en.wikipedia.org/wiki/Variable-length_array). What's the reason for passing plain `const T*` instead of e.g. `const T*[]` or use [templates for the array size](https://stackoverflow.com/questions/3368883/how-does-this-size-of-array-template-function-work) as well? – Some programmer dude Dec 04 '18 at 17:26
  • Is this a [mcve]? Will this question work without using templates? – Tim Randall Dec 04 '18 at 17:43
  • I've updated the code so that it reflects more what I'm working on. The code I'm working on is C++ function which gets called from MATLAB. It will receive a pointer to a multi-dimensional array and the dimensions of the array are passed as parameters. That's the reason the array dimensions are not known at compile time. I've just wanted to convert the pointer to a C-style array because I think the loops are easier to read than instead of using `std::cout << cVector[j + i * dim2] << " ";`. – Martin Stolpe Dec 05 '18 at 08:29
  • What I do not unterstand is why Clang accepts the version where I use the `auto` keyword. Is this also a non-standard extension? – Martin Stolpe Dec 05 '18 at 08:32
  • I did enable the following compiler options for g++ and now it also generates an error: `-Wall -Wextra -Wpedantic`. When I use `-Weverything` Clang will also treat the `auto` variant as error. I'm still puzzled why Clang treats the two definitions differently. – Martin Stolpe Dec 07 '18 at 14:37

1 Answers1

2

This is a non standard g++ extension that is allowing g++ to accept the code. g++ allows you to declare a VLA (Variable Length Array) which is not part of the C++ standard. To make this code standard compliant you can move dim1 and dim2 into the template parameters and pass them as compile time constants like:

template<size_t dim1, size_t dim2, typename T>
void printVector(const T *cVector)
{
    const T (&twoDArray)[dim1][dim2]{*reinterpret_cast<const T (*)[dim1][dim2]>(cVector)};
//    auto twoDArray{*reinterpret_cast<const T (*)[dim1][dim2]>(cVector)};

    std::cout << "Printing 2D array:  " << std::endl;
    for(int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            std::cout << twoDArray[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    const size_t VEC_SIZE_CONST{2};
    double cVector[VEC_SIZE_CONST][VEC_SIZE_CONST]{{1.1, 2.2}, {3.3, 4.4}};
    printVector<VEC_SIZE_CONST, VEC_SIZE_CONST>(&cVector[0][0] );
    return 0;
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402