Consider the following code
=== begin code ===
#include <experimental/optional>
using namespace std::experimental;
struct array_of_optional {
optional<int> v[100];
};
array_of_optional
f(const array_of_optional& a) {
return a;
}
=== end code ===
Compiling with -O3 (6.2.1), I get:
0000000000000000 <f(array_of_optional const&)>:
0: 48 8d 8f 20 03 00 00 lea 0x320(%rdi),%rcx
7: 48 89 f8 mov %rdi,%rax
a: 48 89 fa mov %rdi,%rdx
d: 0f 1f 00 nopl (%rax)
10: c6 42 04 00 movb $0x0,0x4(%rdx)
14: 80 7e 04 00 cmpb $0x0,0x4(%rsi)
18: 74 0a je 24 <f(array_of_optional
const&)+0x24>
1a: 44 8b 06 mov (%rsi),%r8d
1d: c6 42 04 01 movb $0x1,0x4(%rdx)
21: 44 89 02 mov %r8d,(%rdx)
24: 48 83 c2 08 add $0x8,%rdx
28: 48 83 c6 08 add $0x8,%rsi
2c: 48 39 ca cmp %rcx,%rdx
2f: 75 df jne 10 <f(array_of_optional
const&)+0x10>
31: f3 c3 repz retq
However, because we're constructing into the return value, we're under
no obligation to leave the memory untouched, so this can be optimized
into a memcpy, which can be significantly faster if the optionals are
randomly engaged; but gcc doesn't notice that.