Background information about what inspired my question:
I learned about Designated Initializers in C (see here and here: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html), which are awesome, and allow you to initialize C arrays in C like this, which is awesome:
int my_array[] =
{
[MY_ENUM1] = 7,
[MY_ENUM5] = 6,
};
I tried it in C++ and it doesn't work (see my comments under the answer linked-to above). Bummer. I tried it in a C++ std::vector and got behavior I don't understand. What is happening here?
The crux of my question:
What are the [7] = 12 and [10] = 15 doing in my example? What is going on there? Why does that compile? Why is the output the way it is?
I just compiled the below code with -Wall -Wextra -Werror -Wpedantic, and it still compiles with zero warnings. -Wpedantic is one I almost never use, and do not recommend, because it turns off compiler extensions, which I like to keep on. Yet, I still get no warnings with that unusual [7] = 12 syntax.
Update: something seems to be wrong with onlinegdb's ability to accept my compiler flags. With -Wpedantic I do see the warning when I run it locally:
eRCaGuy_hello_world/cpp$ g++ -Wall -Wextra -Werror -Wpedantic -O3 -std=c++17 vector_with_square_brackets.cpp -o bin/a && bin/a
vector_with_square_brackets.cpp:19:5: error: ISO C++ does not allow C99 designated initializers [-Werror=pedantic]
[7] = 12, // Why does this "work" here? What is happening?
^
vector_with_square_brackets.cpp:20:5: error: ISO C++ does not allow C99 designated initializers [-Werror=pedantic]
[10] = 15,
^
cc1plus: all warnings being treated as errors
WithOUT -Wpedantic, however, I see no warnings nor errors:
eRCaGuy_hello_world/cpp$ g++ -Wall -Wextra -Werror -O3 -std=c++17 vector_with_square_brackets.cpp -o bin/a && bin/a
1
2
3
12
15
4
...yet the output still doesn't follow the rules of Designated Initializers either. Am I in the realm of something like a compiler bug? I'd still like more answers and clarity.
My g++ --version is g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0.
See especially my comment in the code below:
Run it online: https://onlinegdb.com/FZ2YdZXJe (gcc compiler set to C++17)
#include <iostream>
#include <vector>
std::vector<int> v =
{
1,
2,
3,
[7] = 12, // Why does this "work" here? What is happening?
[10] = 15,
4,
};
int main()
{
for (int i : v)
{
std::cout << i << "\n";
}
printf("\n");
return 0;
}
Output:
1
2
3
12
15
4
Also, I was actually expecting the output to look like this, assuming it were to act like "designated initializers" in C arrays. Since I didn't get this output, something else I don't understand must be going on (hence this question).
1
2
3
0
0
0
0
12
0
0
15
4
Update: it appears to be a GCC compiler bug
...which exists in version 8.4 (the version I'm using) but was fixed by version 9.1. See the comment below this answer:
I would say, this was a general issue with previous versions of the compilers, because GCC 8.4 does compile it: https://godbolt.org/z/xqYq6jeb8. Since version 9.1, errors starts to occur. – Erdal Küçük
Quick answer
It does not, it is non standard. It's a compiler bug. GCC version 8.4 (the version of the OP) compiles without any warnings and or errors (see: https://godbolt.org/z/xqYq6jeb8). After version 9.1, errors will start to occur.
Details
For a short overview, have a look at: https://www.modernescpp.com/index.php/designated-initializers.
Especially at the paragraph: https://www.modernescpp.com/index.php/designated-initializers#h2-1-differences-between-c-and-c
Have a look at the GCC page: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
There you can read the following:
Since you're working with
std::vector, have a look at how avectorcan be constructed: https://en.cppreference.com/w/cpp/container/vector/vectorThe constructor listed in no. 10
vector(std::initializer_list<T> init)allows the initialization like this:The documentation to initializer-list can be found here: https://en.cppreference.com/w/cpp/utility/initializer_list
General initialization in C++: https://en.cppreference.com/w/cpp/language/initialization
The initialization type you're most interested in would be: Aggregate initialization
There, in the section Designated initializers, you will be able to read the following:
After some discussions, we found out, that the issues have to do something with the different implementations of the compiler (versions).
Since the standard and e.g. the compiler GCC states, that designated initializers are supported in the C but not in the C++ language, still GCC version 8.4 (the version of the OP) compiles without any warnings and or errors (see: https://godbolt.org/z/xqYq6jeb8). After version 9.1, errors will start to occur.