Aujourd’hui, j’ai découvert un bug dans MSVC, le compilateur de Microsoft fourni par Visual Studio. Et tout a commencé par un commentaire de @BIOoOAG sur le tutoriel C++. Pendant qu’il lisait le chapitre sur les lambdas, il nous a écrit un message signalant que le code suivant produisait chez lui deux warnings.
#include <iostream>
int main()
{
bool const a_boolean { true };
int const an_integer { 42 };
double const a_real { 3.1415 };
auto lambda = [a_boolean, an_integer, a_real]() -> void
{
std::cout << "Boolean is " << std::boolalpha << a_boolean << "." << std::endl;
std::cout << "Integer is " << an_integer << "." << std::endl;
std::cout << "Real is " << a_real << "." << std::endl;
};
lambda();
return 0;
}
Avec MinGW, il avait les deux warnings suivants.
warning: lambda capture 'a_boolean' is not required to be capture for this use. [-Wunused-lambda-capture]
warning: lambda capture 'an_integer' is not required to be capture for this use. [-Wunused-lambda-capture]
Bizarre, avec Visual Studio je n’ai jamais eu ce problème. Comme mes recherches ne donnent rien, je me décide à demander sur SO. La réponse tombe : MinGW et GCC ont raison, MSVC ne respecte pas la norme. En effet, le code suivant, valide, ne compile pas avec le compilateur de Microsoft.
#include <iostream>
int main()
{
bool const a_boolean { true };
int const an_integer { 42 };
double const a_real { 3.1415 };
// Notez que a_boolean et an_integer ne sont plus explicitement capturés.
auto lambda = [a_real]() -> void
{
std::cout << "Boolean is " << std::boolalpha << a_boolean << "." << std::endl;
std::cout << "Integer is " << an_integer << "." << std::endl;
std::cout << "Real is " << a_real << "." << std::endl;
};
lambda();
return 0;
}
La deuxième réponse à cette question dévoile les passages de la norme, soit dit en passant assez compliqués à comprendre, qui expliquent la raison.
Pour la première fois de ma vie, j’ai pu blâmer le compilateur si mon code ne compilait pas.