Context: I thought that the following SSCCE, compiled with compile: g++ -std=c++11 main.cpp
, would zero-initialise a fixed-size array arr
:
void foo(int arr[4] = {0}) { }
int main(int argc, char const *argv[]) {
foo();
return 0;
}
However, I debugged with gdb
and found out that arr = 0x0
(null). I (wildly) guess this is because int arr[4]
is very much like int* arr
but additionally telling the compiler to only allow arrays of length 4. Hence, what actually happens is int arr* = {0}
ie I am just using an initializer-list to zero-initialize a pointer.
I know I can circumvent this problem by reverting back to using overloads instead of default arguments:
void foo(int arr[4]) { }
void foo() {
int arr[4] = {0};
foo(arr);
}
This does give me a zero-initialized fixed-size array in foo
, as expected. However, I think it would be nice to merge these two overloaded functions into one by using some default argument, similarly to the SSCCE.
Question: Is zero-initialisation of a default argument fixed-size array possible in C++11. If so, how?
The main problem you are encountering is that void foo(int arr[4])
decays to void foo(int* arr)
, so your function does actually accept a pointer instead of an array. The simple proof is that foo(nullptr);
will compile without errors or warnings.
As such the declaration void foo(int arr[4] = {0});
is actually void foo(int* arr = {0});
which initializes the pointer to 0 (trying to change {0}
to any other number will actually cause a compile time error).
The best alternative is most likely to use std::array
instead, for example:
#include <array>
void foo(std::array<int, 4> arr = {0}) { }
int main(int argc, char const *argv[]) {
foo();
// call with an array
foo({1,2,3,4});
// providing more values will cause a compile time error
// foo({2,3,4,5,6,7,8});
return 0;
}
Note that currently there is no convenient way to convert "raw" C-style arrays to std::array, though there is a helper function in experimental/array
called std::to_array
which may be merged into the standard in a future version