Consider this code (using CString because it's familiar and easy to see when not constructed, but nothing special about the class), tested under Visual Studio 2008:
CString DoSomething( const CString& sString )
{
return sString;
}
CString sTest1 = DoSomething( sTest1 ); // Compiles (no warnings), fails at runtime
CString sTest2( DoSomething( sTest2 ) ); // Doesn't compile
CString sTest3; sTest3 = DoSomething( sTest3 ); // Compiles, self-assignment, works
As I understand the C++ standard, Test1 can be compiled into Test2 automatically as a compile-time optimization, provided the appropriate constructor is available (which, by default, will be generated to be identical to the first test). Notably, however, the behavior is not the same as Test3, which will work correctly.
Now I understand why Test1 does not work, and why Test2 does not compile. What I am curious about is why Test1 compiles in the first place? Is this permitted in the standard, open for interpretation, a flaw in VS2008's compiler, a deficiency in init-before-use static checking, or what? Is there any way to force the compiler to at least give a warning in this case (Test1 appears to compile clean with max warning level under VS2008)? What would be the justification for the C++ specification permitting this construct?
Edit: Alternatively, is there any way to force the compiler to compile Test1 as Test2 (and thus trigger the error)?
Edit to add verbatim error message for Test2: error C2065: 'sTest2' : undeclared identifier