Let's say I have a function like:
int test(std::array<char, 8>* data) {
char buffer[data->size() * 2];
[... some code ...]
}
clearly the size of the buffer can be evaluated at compile time: data has a constexpr
size of 8 elements, 8 * 2 = 16 bytes.
However, when compiling with -Wall
, -pedantic
and -std=c++11
I get the infamous error:
warning: variable length arrays are a C99 feature [-Wvla-extension]
which I believe makes sense: array::size()
is constexpr
, but it is still a method, and in the function above we still have to dereference a pointer, which is not constexpr
.
If I try something like:
int test(std::array<char, 8>& data) {
char buffer[data.size() * 2];
[...]
}
gcc
(tried version 5.2.0) seems happy: there is no warning.
But with clang++
(3.5.1) I still get a warning complaining about variable length arrays.
In my case, I can't easily change the signature of test
, it has to take a pointer. So... a few questions:
What is the best / most standard way to get the size of a std::array
pointer in constexpr context?
Is the difference in behavior with pointers vs references expected? Which compiler is right about the warning, gcc
or clang
?
I do not know about 2.
But for 1, we can do this:
template<class T, size_t N>
constexpr std::integral_constant<size_t, N> array_size( std::array<T, N> const& ) {
return {};
}
then:
void test(std::array<char, 8>* data) {
using size=decltype(array_size(*data));
char buffer[size{}];
(void)buffer;
// [... some code ...]
}
alternatively:
template<class T, class U, size_t N>
std::array<T,N> same_sized_array( std::array< U, N > const& ) {
return {};
}
void test(std::array<char, 8>* data) {
auto buffer = same_sized_array<char>(*data);
(void)buffer;
// [... some code ...]
}
finally, a C++14 cleanup:
template<class A>
constexpr const decltype(array_size( std::declval<A>() )) array_size_v = {};
void test3(std::array<char, 8>* data) {
char buffer[array_size_v<decltype(*data)>];
(void)buffer;
// [... some code ...]
}
Live example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With