Test Code:
#include <array>
int test(const std::array<int, 10> &arr) {
return arr[9];
}
I want to make arr[0]
as efficient as C style array, which means inline STL array [] operator function.
I have checked the generate assembly code:
$ g++ --std=c++17 -c test.cpp && objdump -d -C test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <test(std::array<int, 10ul> const&)>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 7d f8 mov %rdi,0xfffffffffffffff8(%rbp)
c: 48 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%rax
10: be 09 00 00 00 mov $0x9,%esi
15: 48 89 c7 mov %rax,%rdi
18: e8 00 00 00 00 callq 1d <test(std::array<int, 10ul> const&)+0x1d>
1d: 8b 00 mov (%rax),%eax
1f: c9 leaveq
20: c3 retq
Disassembly of section .text._ZNKSt5arrayIiLm10EEixEm:
0000000000000000 <std::array<int, 10ul>::operator[](unsigned long) const>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 7d f8 mov %rdi,0xfffffffffffffff8(%rbp)
c: 48 89 75 f0 mov %rsi,0xfffffffffffffff0(%rbp)
10: 48 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%rax
14: 48 8b 55 f0 mov 0xfffffffffffffff0(%rbp),%rdx
18: 48 89 d6 mov %rdx,%rsi
1b: 48 89 c7 mov %rax,%rdi
1e: e8 00 00 00 00 callq 23 <std::array<int, 10ul>::operator[](unsigned long) const+0x23>
23: c9 leaveq
24: c3 retq
Disassembly of section .text._ZNSt14__array_traitsIiLm10EE6_S_refERA10_Kim:
0000000000000000 <std::__array_traits<int, 10ul>::_S_ref(int const (&) [10], unsigned long)>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 89 7d f8 mov %rdi,0xfffffffffffffff8(%rbp)
8: 48 89 75 f0 mov %rsi,0xfffffffffffffff0(%rbp)
c: 48 8b 45 f0 mov 0xfffffffffffffff0(%rbp),%rax
10: 48 8d 14 85 00 00 00 lea 0x0(,%rax,4),%rdx
17: 00
18: 48 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%rax
1c: 48 01 d0 add %rdx,%rax
1f: 5d pop %rbp
20: c3 retq
arr[9]
is a function call 1d <test(std::array<int, 10ul> const&)+0x1d>
in generated code.
If I specified the optimization level, the STL function is inlined as expect:
$ g++ --std=c++17 -Og -c test.cpp && objdump -d -C test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <test(std::array<int, 10ul> const&)>:
0: 8b 47 24 mov 0x24(%rdi),%eax
3: c3 retq
But my real project is a big project, I can't change the global compile optimization flag. So I want to specified the optimization flag for some files.
So I add #pragma GCC optimize ("string"...)
in my program:
#pragma GCC optimize ("-Og")
#include <array>
int test(const std::array<int, 10> &arr) {
return arr[9];
}
This option make some sense indeed:
$ g++ --std=c++17 -c test.cpp && objdump -d -C test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <test(std::array<int, 10ul> const&)>:
0: 48 83 ec 08 sub $0x8,%rsp
4: be 09 00 00 00 mov $0x9,%esi
9: e8 00 00 00 00 callq e <test(std::array<int, 10ul> const&)+0xe>
e: 8b 00 mov (%rax),%eax
10: 48 83 c4 08 add $0x8,%rsp
14: c3 retq
Disassembly of section .text._ZNKSt5arrayIiLm10EEixEm:
0000000000000000 <std::array<int, 10ul>::operator[](unsigned long) const>:
0: 48 83 ec 08 sub $0x8,%rsp
4: e8 00 00 00 00 callq 9 <std::array<int, 10ul>::operator[](unsigned long) const+0x9>
9: 48 83 c4 08 add $0x8,%rsp
d: c3 retq
Disassembly of section .text._ZNSt14__array_traitsIiLm10EE6_S_refERA10_Kim:
0000000000000000 <std::__array_traits<int, 10ul>::_S_ref(int const (&) [10], unsigned long)>:
0: 48 8d 04 b7 lea (%rdi,%rsi,4),%rax
4: c3 retq
The <std::array<int, 10ul>::operator[]
& __array_traits
functions ard optimized, but we can see, there still a function call: callq e <test(std::array<int, 10ul> const&)+0xe>
.
So I wonder why #pragma GCC optimize ("-Og")
does take effect as I expect. And I want to know how to force inline STL function for a specified file?
Note: GCC version: 8.2