The problem
I have made some tests on compiler-explorer about std::optional
, and to my surprise, it seems like it behaves like a pointer, even though it is stated in the standard (§23.6.3) that it should contain it:
Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value.
The tests
The full code I tested is on this compiler-explorer sheet, although I don't know how much time it will remain up. That is why I will describe here the tests I made.
What I am testing
I am making two tests with one function each:
- Checking if the value is there
- Checking if the value is there and retrieval of it if it is there, or 67780 otherwise
I used -O2
minimum and --std=c++17
as compiler flags for both gcc 7.2 and clang 5.0.0 on for the x86_64 target. The results copied here are from clang.
Using std::optional
Checking
Code:
bool check(const std::optional<int> maybe_int) {
return maybe_int.has_value();
}
Result:
mov al, byte ptr [rdi + 4]
ret
One indirection.
Retrieving
Code:
int retrieve(const std::optional<int> maybe_int) {
if(maybe_int.has_value())
return maybe_int.value();
else
return 67780;
}
Result:
cmp byte ptr [rdi + 4], 0
je .LBB1_1
mov eax, dword ptr [rdi]
ret
.LBB1_1:
mov eax, 67780
ret
One indirection for checking, one for retrieving.
Using a custom class
The class
template<typename T>
class my_optional {
private:
T val;
bool has_val;
public:
/* Constuctors ... */
bool has_value() const {
return has_val;
}
decltype(auto) value() const {
return val;
}
};
Checking
Code:
bool check(const my_optional<int> maybe_int) {
return maybe_int.has_value();
}
Result:
shr rdi, 32
test dil, dil
setne al
ret
No indirections.
Retrieving
Code:
int retrieve(const my_optional<int> maybe_int) {
if(maybe_int.has_value())
return maybe_int.value();
else
return 67780;
}
Result:
movabs rax, 1095216660480
test rdi, rax
mov eax, 67780
cmovne eax, edi
ret
Although I don't know how that works, it does not have any indirections.
The questions
Either the title or "What is wrong with my tests ?"