Когда я компилирую и запускаю этот код с помощью Clang (-O3
) или MSVC (/O2
)...
#include <stdio.h>
#include <time.h>
static int const N = 0x8000;
int main()
{
clock_t const start = clock();
for (int i = 0; i < N; ++i)
{
int a[N]; // Never used outside of this block, but not optimized away
for (int j = 0; j < N; ++j)
{
++a[j]; // This is undefined behavior (due to possible
// signed integer overflow), but Clang doesn't see it
}
}
clock_t const finish = clock();
fprintf(stderr, "%u ms\n",
static_cast<unsigned int>((finish - start) * 1000 / CLOCKS_PER_SEC));
return 0;
}
... цикл не оптимизируется.
Кроме того, ни Clang 3.6 и Visual С++ 2013 и GCC 4.8.1 сообщает мне, что переменная неинициализирована!
Теперь я понимаю, что отсутствие оптимизации не является ошибкой как таковой, но я нахожу это удивительным, учитывая, что компиляторы должны быть довольно умными в наши дни. Это похоже на такой простой фрагмент кода, что даже методы анализа жизнеспособности с десятилетия назад должны уметь оптимизировать переменную a
и, следовательно, весь цикл - не обращайте внимания на то, что приращение переменной уже undefined.
Но только GCC может понять, что это no-op, и ни один из компиляторов не говорит мне, что это неинициализированная переменная.
Почему это? Что мешает анализу простой жизнеспособности сообщить компилятору, что a
не используется? Более того, почему компилятор не обнаруживает, что a[j]
неинициализирован в первую очередь? Почему существующие неинициализированные переменные-детекторы во всех этих компиляторах не улавливают эту очевидную ошибку?