This is my attempt to answer my question, at least on the GCC. My understanding of gcc assembler output is not fantastic, so please correct if necessary.
Using initializer_test.cpp :
#include <vector> int main() { std::vector<long> values = { 123456, 123457, 123458 }; return 0; }
And compiling using gcc v4.6.3 using the following command line:
g++ -Wa,-adhln -g initializer_test.cpp -masm=intel -std=c++0x -fverbose-asm | c++filt | view -
I get the following output (cut out for reliable bits):
5:initializer_test.cpp **** std::vector<long> values = { 123456, 123457, 123458 }; 100 .loc 2 5 0 101 0009 488D45EF lea rax, [rbp-17] # tmp62, 102 000d 4889C7 mov rdi, rax #, tmp62 103 .cfi_offset 3, -24 104 0010 E8000000 call std::allocator<long>::allocator() # 104 00 105 0015 488D45D0 lea rax, [rbp-48] # tmp63, 106 0019 BA030000 mov edx, 3 #, <-- Parameter 3 106 00 107 001e BE000000 mov esi, OFFSET FLAT:._42 #, <-- Parameter 2 107 00 108 0023 4889C7 mov rdi, rax #, tmp63 <-- Parameter 1 109 0026 E8000000 call std::initializer_list<long>::initializer_list(long const*, unsigned long) # 109 00 110 002b 488D4DEF lea rcx, [rbp-17] # tmp64, 111 002f 488B75D0 mov rsi, QWORD PTR [rbp-48] # tmp65, D.10602 112 0033 488B55D8 mov rdx, QWORD PTR [rbp-40] # tmp66, D.10602 113 0037 488D45B0 lea rax, [rbp-80] # tmp67, 114 003b 4889C7 mov rdi, rax #, tmp67 115 .LEHB0: 116 003e E8000000 call std::vector<long, std::allocator<long> >::vector(std::initializer_list<long>, std::allocator<long> const&) # 116 00 117 .LEHE0: 118 .loc 2 5 0 is_stmt 0 discriminator 1 119 0043 488D45EF lea rax, [rbp-17] # tmp68, 120 0047 4889C7 mov rdi, rax #, tmp68 121 004a E8000000 call std::allocator<long>::~allocator() #
and
1678 .section .rodata 1679 0002 00000000 .align 16 1679 00000000 1679 00000000 1679 0000 1682 ._42: 1683 0010 40E20100 .quad 123456 1683 00000000 1684 0018 41E20100 .quad 123457 1684 00000000 1685 0020 42E20100 .quad 123458 1685 00000000
Now, if I understand correctly the call on line 109 in the context of the x86-64 System V AMD64 ABI call convention (the parameters that I annotated to list the code), this shows that the underlying array is stored in .rodata , which I accept as the same memory, as well as static constant data. At least for gcc 4.6.
Performing a similar test, but with optimizations enabled ( -O2 ), initializer_list seems to be optimized:
70 .file 2 "/usr/include/c++/4.6/ext/new_allocator.h" 71 .loc 2 92 0 72 0004 BF180000 mov edi, 24 #, 72 00 73 0009 E8000000 call operator new(unsigned long) # 73 00 74 .LVL1: 75 .file 3 "/usr/include/c++/4.6/bits/stl_algobase.h" 76 .loc 3 366 0 77 000e 488B1500 mov rdx, QWORD PTR ._42[rip] # ._42, ._42 77 000000 90 .file 4 "/usr/include/c++/4.6/bits/stl_vector.h" 91 .loc 4 155 0 92 0015 4885C0 test rax, rax # D.11805 105 .loc 3 366 0 106 0018 488910 mov QWORD PTR [rax], rdx #* D.11805, ._42 107 001b 488B1500 mov rdx, QWORD PTR ._42[rip+8] # ._42, ._42 107 000000 108 0022 48895008 mov QWORD PTR [rax+8], rdx #, ._42 109 0026 488B1500 mov rdx, QWORD PTR ._42[rip+16] # ._42, ._42 109 000000 110 002d 48895010 mov QWORD PTR [rax+16], rdx #, ._42 124 .loc 4 155 0 125 0031 7408 je .L8 #, 126 .LVL3: 127 .LBB342: 128 .LBB343: 129 .loc 2 98 0 130 0033 4889C7 mov rdi, rax #, D.11805 131 0036 E8000000 call operator delete(void*) #
In general, std::initializer_list looks pretty optimal in gcc.