Рассмотрим этот код (использующий CString, потому что он знаком и его легко увидеть, когда он не создан, но ничего особенного в классе), протестированного в 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
Как я понимаю, стандарт C ++, Test1 может быть автоматически скомпилирован в Test2 как оптимизация во время компиляции, если доступен соответствующий конструктор (который по умолчанию будет сгенерирован так же, как и первый тест). Примечательно, однако, что поведение не совпадает с Test3, что будет работать правильно.
Теперь я понимаю, почему Test1 не работает и почему Test2 не компилируется. Что меня интересует, так это то, почему Test1 компилируется в первую очередь? Разрешено ли это в стандарте, открытом для интерпретации, в компиляторе VS2008, в статической проверке init-before-use или как? Есть ли способ заставить компилятор хотя бы выдать предупреждение в этом случае (Test1, по-видимому, компилирует чистый с максимальным уровнем предупреждения в соответствии с VS2008)? Что будет оправданием для спецификации C ++, разрешающей эту конструкцию?
Редактировать: В качестве альтернативы, есть ли способ заставить компилятор скомпилировать Test1 как Test2 (и таким образом вызвать ошибку)?
Изменить, чтобы добавить дословное сообщение об ошибке для Test2:
ошибка C2065: 'sTest2': необъявленный идентификатор