Lorsque je compile et exécute ce code avec Clang (-O3
) ou MSVC (/O2
)...
#include
#include
static int const N = 0x8000;
int main()
{
clock_t const start = clock();
for (int i = 0; i < N; ++i)
{
int a[N]; // Jamais utilisé en dehors de ce bloc, mais pas optimisé
for (int j = 0; j < N; ++j)
{
++a[j]; // C'est aussi un comportement indéfini, mais Clang ne le voit pas
}
}
clock_t const finish = clock();
fprintf(stderr, "%u ms\n",
static_cast((finish - start) * 1000 / CLOCKS_PER_SEC));
return 0;
}
... la boucle n'est pas optimisée.
De plus, ni Clang 3.6 ni Visual C++ 2013 ni GCC 4.8.1 ne me dit que la variable est non initialisée !
Maintenant je réalise que le manque d'optimisation n'est pas un bug en soi, mais je trouve cela étonnant étant donné que les compilateurs sont censés être assez intelligents de nos jours. Il semble que même des techniques d'analyse de vieillesse datant d'une décennie devraient pouvoir prendre en charge l'optimisation de la variable a
et donc de toute la boucle -- peu importe le fait que l'incrémentation de la variable est déjà un comportement indéfini.
Pourtant, seul GCC est capable de comprendre que c'est un no-op, et aucun des compilateurs ne me dit qu'il s'agit d'une variable non initialisée.
Pourquoi cela ? Qu'empêche une simple analyse de vivacité de dire au compilateur que a
est inutilisé ? De plus, pourquoi le compilateur ne détecte-t-il pas que a[j]
est non initialisé en premier lieu ? Pourquoi les détections existantes de variables non initialisées dans tous ces compilateurs ne peuvent-elles pas attraper cette erreur évidente ?