Ce qui suit est absurde encore compile proprement avec g++ -Wall -Wextra -Werror -Winit-self
(j'ai testé GCC 4.7.2 et 4.9.0):
#include <iostream>
#include <string>
int main()
{
for (int ii = 0; ii < 1; ++ii)
{
const std::string& str = str; // !!
std::cout << str << std::endl;
}
}
La ligne marquée !!
entraîne un comportement non défini, mais n'est pas diagnostiquée par GCC. Toutefois, en commentant l' for
ligne la GCC se plaindre:
error: ‘str' is used uninitialized in this function [-Werror=uninitialized]
Je voudrais savoir: pourquoi est-GCC si facilement berner ici? Lorsque le code n'est pas dans une boucle, GCC sait que c'est faux. Mais mettre le même code dans une boucle simple et GCC ne plus comprendre. Ce qui me dérange, car nous comptons beaucoup sur le compilateur de nous informer lorsque nous faisons des erreurs stupides en C++, mais il échoue pour une apparence cas trivial.
Bonus trivia:
- Si vous modifiez
std::string
deint
et tourner sur l'optimisation, la GCC devra en diagnostiquer l'erreur, même avec la boucle. - Si vous générez le code cassé avec
-O3
, GCC littéralement appelle la ostream insérer une fonction avec un pointeur null pour l'argument chaîne. Si vous pensiez que vous étiez à l'abri de références null si vous n'avez pas à faire des casting, détrompez-vous.
J'ai déposé un bug de GCC pour cela: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63203 - je voudrais encore pour obtenir une meilleure compréhension de ce qui s'est passé et comment il peut avoir un impact sur la fiabilité des diagnostics similaires.