0

I want to convert a float vector to a float array in C++ 20. I searched online and found this solution:

#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> input({ 1, 2, 3, 4, 5 });
 
    int arr[input.size()];
    std::copy(input.begin(), input.end(), arr);
 
    for (int i: arr) {
        std::cout << i << ' ';
    }
 
    return 0;
}

But when I try to implement it, the compiler gives me an error saying that what's inside the brackets in the array declaration must be a constant expression.

Since when is this the case? I swear I've declared arrays in a similar manner in C++ before and it worked. And if you look online you'll see that everyone does this too, the example I posted seems to be the standard solution to my problem. So why does it give me an error?

9
  • It's non-standard. gcc (and possibly clang) support it, but it's not recommended. Commented Oct 10, 2022 at 11:23
  • The size must be fixed at compile-time. But why do you want an array to begin with? Commented Oct 10, 2022 at 11:24
  • 3
    Just pass my_vector.data() Commented Oct 10, 2022 at 11:28
  • 5
    @Pepis Nothing in GL requires specifically an array. They receive pointers, and you can get one from a vector using vector.data(). Commented Oct 10, 2022 at 11:28
  • 2
    I didn't know vector.data() was a thing, thanks guys :) Commented Oct 10, 2022 at 11:31

1 Answer 1

9

Since when is this the case?

Since always. In standard C++, you cannot allocate a block of memory on the stack if you don't know its size at compile time.

Some compilers allow it as an extension. It's also standard in C99, and these arrays are then known as variable-length array.

A lot of what you see online is non standard. Just because someone does something that works for them doesn't mean it will work for you. In this case, it can certainly work for you if you don't care about writing cross-platform, standard compliant code. But if you want to write standard compliant code, you have basically two choices: make an array with a large enough size, known at compile time, and only use part of it, or don't use an array.

To address your comment:

Because a third party function (OpenGL) requires an array as an argument.

No function requires an array as argument. It can require a raw block of memory, but then you also need to give it the size of that block. You can easily do that with a std::vector, using the methods data() and size().

The only way I know of to require an array as argument is through some template magic:

template<std::size_t N>
void print_size(int (&array)[N]) {
    std::cout << N;
}

Demo

Even then, you can apparently pass it a vector if you specify the size (might be undefined behavior):

std::vector<int> v = {1, 2, 3};
print_size<3>(reinterpret_cast<int(&)[3]>(*v.data()));
Sign up to request clarification or add additional context in comments.

1 Comment

That casting is pedantically UB (even if it may work in practice).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.