バグが原因で、このコードがVisual Studio 17で正常にコンパイルされ、おそらく他のコンパイラでも同様にコンパイルされることがわかりました。なぜ私は興味がありますか?
#include <iostream>
#include <string>
std::string foo(){
return nullptr;
}
int main(){
auto s = foo();
std::cout << s << std::endl;
}
std::basic_string
c'torがchar*
で呼び出される可能性があり、ptrからstd::string
への暗黙の変換を返すときに(NULL
を引数として)そして、それが不幸になります)。私は正しい道を進んでいますか?
はい、あなたの仮定は正しいです。チェック _std::basic_string
_コンストラクタ#5 が呼び出されます:
_basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
_
nullptr
を渡すと、 標準 と注記に記載されているように、未定義の動作が呼び出されることに注意してください。
[s, s + Traits::length(s))
が有効な範囲でない場合の動作は定義されていません(、たとえばs
がnullポインターの場合 )。
なぜコンパイルしないのですか? std::string
には次のコンストラクタがあります:
string(const CharT* s, const Allocator& alloc = Allocator());
これは、s
が指すnullで終了する文字列のコピーで初期化された内容で文字列を構築します。コンストラクタはnot明示的であるため、nullptr
からstd::string
への暗黙的な変換は実際に可能です。