0

I am essentially trying to write a function that acts as np.reshape, but in C++. I want to take an input matrix, define the dimensions of the output matrix, and have the code create an output array of the appropriate size. I am working in Microsoft Visual Studio 2019, and have changed over to the ISO C++ 17 Standard. I know that C++ was not designed to support variable length arrays, but am trying to find a workaround.

int8_t reshape(int8_t **inputMatrix, int outputRows, int outputCols) {
int inputRows = sizeof(inputMatrix) / sizeof(inputMatrix[0]);
int inputCols = sizeof(inputMatrix[0]);
int ii = 0; int jj = 0;
int8_t outputMatrix[outputRows][outputCols];
for (int i = 0; i < inputRows; i++) {
    for (int j = 0; j < inputCols; j++) {
        outputMatrix[ii][jj] = inputMatrix[i][j];
        jj++;
        if (jj == outputCols) {
            jj = 0;
            ii++;
        }

    }
}
return outputMatrix;

}

I am receiving the following errors:

  1. In the line int8_t outputMatrix[outputRows][outputCols];, I am getting a double error of "E0028 - expression must have a constant value" in reference to the variables outputRows and outputCols.
  2. In the same line, there is another double error "C2131 - expression did not evaluate to a constant"
  3. In the line outputMatrix[ii][jj] = inputMatrix[i][j]; there is an error "C3863 - array type 'int8_t [outputRows][outputCols]' is not assignable"

In the final purpose for this code it would be okay to use malloc/calloc, but I haven't been able to make that work.

  • 6
    `std::vector` is the workaround for VLA's. – NathanOliver Jan 13 '21 at 17:16
  • 3
    Since you want a matrix, [here's a simple and efficient one](https://stackoverflow.com/a/2076668/4581301). – user4581301 Jan 13 '21 at 17:23
  • 1
    BTW, the code you are using to calculate `inputRows` and `inputColls` is wrong. `sizeof(inputMatrix)` will evaluate to the size of a pointer, not what you are expecting to see. `sizeof(inputMatrix[0]` will also evaluate to the size of a pointer. – R Sahu Jan 13 '21 at 17:27
  • 2
    Also note that it's really, really hard to return a raw array. [Arrays decay](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) to pointers, so you wind up returning a pointer to an array that's going out of scope and no longer valid as soon as the function returns. By the time the caller gets the pointer, there is no array. – user4581301 Jan 13 '21 at 17:28
  • 1
    There are no VLA's in Visual C++ (and ISO C++) hence no way to initialize them. – rustyx Jan 13 '21 at 17:36
  • There are no VLAs in C++. Insisting on them makes the question not reproducable. Please check whether this is a https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem and ask differently. Assuming that will not work, I close-vote for not reproducable. – Yunnosch Jan 13 '21 at 18:26

1 Answers1

0

You can try to use this library if a third-party library is acceptable to you: VLA for C++

And then you can write your code like this:

#include "dynarray.hpp"

vla::dynarray<vla::dynarray<int8_t>> reshape(vla::dynarray<vla::dynarray<int8_t>> &inputMatrix,
                                             int outputRows, int outputCols)
{
    int inputRows = inputMatrix.size();
    int inputCols = inputMatrix[0].size();
    int ii = 0; int jj = 0;
    vla::dynarray<vla::dynarray<int8_t>> outputMatrix(outputRows, outputCols);
    outputMatrix = inputMatrix; // assign value only, size will not be changed.

    return outputMatrix;
}

or even bettter:

vla::dynarray<int8_t, 2> reshape(vla::dynarray<int8_t, 2> &inputMatrix,
                                 int outputRows, int outputCols)
{
    int inputRows = inputMatrix.size();
    int inputCols = inputMatrix[0].size();
    int ii = 0; int jj = 0;
    vla::dynarray<int8_t, 2> outputMatrix(outputRows, outputCols);
    outputMatrix = inputMatrix; // assign value only, size will not be changed.

    return outputMatrix;
}