En raison d'un bogue, je viens de découvrir que ce code se compile bien avec Visual Studio 17 et probablement aussi avec d'autres compilateurs. Maintenant, je suis curieux de savoir pourquoi?
#include <iostream>
#include <string>
std::string foo(){
return nullptr;
}
int main(){
auto s = foo();
std::cout << s << std::endl;
}
Je pourrais imaginer que c'est parce que le std::basic_string
c'tor pourrait être invoqué avec un char*
et en renvoyant une conversion implicite de ptr en std::string
se produit (avec NULL
comme argument, puis passe poof). Suis-je sur la bonne voie?
Oui, votre hypothèse est bonne, la vérification std::basic_string
Constructeurs # 5 sera appelée:
basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
Notez que passer nullptr
appelle un comportement indéfini comme indiqué dans la norme et les notes:
Le comportement n'est pas défini si
[s, s + Traits::length(s))
n'est pas une plage valide ( par exemple, sis
est un pointeur nul ).
Pourquoi ne compilerait-il pas? std::string
a le constructeur suivant:
string(const CharT* s, const Allocator& alloc = Allocator());
qui construit la chaîne avec le contenu initialisé avec une copie de la chaîne de caractères terminée par un pointeur pointé par s
. Le constructeur est pas explicite, donc la conversion implicite de nullptr
en std::string
est en effet possible.