This is called as copy elision.
The compilers are allowed to do this optimization. Though it is not guaranteed by the standard any commercial compiler will perform this optimization whenever it can.
Standard Reference:
C++03 12.8.15:
[...] This elision of copy operations is
permitted in the following
circumstances (which may be combined
to eliminate multiple copies):
[...]
- when a temporary class object that has
not been bound to a reference (12.2)
would be copied to a class object with
the same cv-unqualified type, the copy
operation can be omitted by
constructing the temporary object
directly into the target of the
omitted copy
You might use some compiler settings to disable this optimization, like in case of gcc, from the man page:
-fno-elide-constructor
The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and
forces G++ to call the copy constructor in all cases.
However, using this makes your code non portable across different compilers.