Reputation: 1701
Here a piece of C++ code.
In this example, many code blocks look like constructor calls. Unfortunately, block code #3 is not (You can check it using https://godbolt.org/z/q3rsxn and https://cppinsights.io).
I think, it is an old C++ notation and it could explain the introduction of the new C++11 construction notation using {} (cf #4).
Do you have an explanation for T(i)
meaning, so close to a constructor notation, but definitely so different?
struct T {
T() { }
T(int i) { }
};
int main() {
int i = 42;
{ // #1
T t(i); // new T named t using int ctor
}
{ // #2
T t = T(i); // new T named t using int ctor
}
{ // #3
T(i); // new T named i using default ctor
}
{ // #4
T{i}; // new T using int ctor (unnamed result)
}
{ // #5
T(2); // new T using int ctor (unnamed result)
}
}
NB: thus, T(i)
(#3) is equivalent to T i = T()
;
Upvotes: 18
Views: 884
Reputation: 727
You can use Compiler Explorer to see what happens in assembler.
You can see that #1,#2 #4 and #5 do same thing but strangly #3 call the other constructor (the base object constructor).
Does anyone have an explanation?
Assembler code :
::T() [base object constructor]:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
nop
pop rbp
ret
T::T(int):
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov DWORD PTR [rbp-12], esi
nop
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 42
// #1
mov edx, DWORD PTR [rbp-4]
lea rax, [rbp-7]
mov esi, edx
mov rdi, rax
call T::T(int)
// #2
mov edx, DWORD PTR [rbp-4]
lea rax, [rbp-8]
mov esi, edx
mov rdi, rax
call T::T(int)
// #3
lea rax, [rbp-9]
mov rdi, rax
call T::T() [complete object constructor]
// #4
mov edx, DWORD PTR [rbp-4]
lea rax, [rbp-6]
mov esi, edx
mov rdi, rax
call T::T(int)
// #5
lea rax, [rbp-5]
mov esi, 2
mov rdi, rax
call T::T(int)
mov eax, 0
leave
ret
Upvotes: -1
Reputation: 119382
The statement:
T(i);
is equivalent to:
T i;
In other words, it declares a variable named i
with type T
. This is because parentheses are allowed in declarations in some places (in order to change the binding of declarators) and since this statement can be parsed as a declaration, it is a declaration (even though it might make more sense as an expression).
Upvotes: 17