2014-10-23 3 views
3
#include <iostream> 

int main() 
{ 
    int n = -1000; 
    for (int i(0); i != n; ++i) 
    { 
    } 
} 

В НКУ следующая ошибка поймана во время компиляции:Может ли clang предупреждать о неопределенном поведении во время компиляции?

main.cpp:6:5: warning: iteration 2147483647u invokes undefined behavior [-Waggressive-loop-optimizations] 

    for (int i(0); i != n; ++i) 

Clang-х -fsanitize=undefined механизм времени выполнения. Что такое эквивалент времени компиляции клана?

+1

Это, кажется, очень недавняя функция GCC (она находится в 4.9, но не 4.8). Я не удивлюсь, если у Клана еще этого нет. И, конечно, многие случаи, подобные этому, не могут быть обнаружены во время выполнения; это работает только потому, что значение 'n' известно во время компиляции. –

+0

'-Wall' поймает вещи, которые приведут к UB во время компиляции в качестве предупреждения. – Rapptz

+0

@ Rapptz, но это не для этого случая, и это, по общему признанию, ультра конкретный вопрос. – rubenvb

ответ

6

Неопределенное поведение часто описывается как таковое в стандарте, поскольку компилятору сложно проверить это во всех ситуациях.

Вы просто столкнулись с одним случаем, который обрабатывается GCC, а не Clang. Если вы посмотрите, вы сможете найти случаи, которые обрабатываются одним, но не другим компилятором. Это потому, что они не являются одним и тем же компилятором и имеют разные анализы, которые они выполняют.

+4

И действительно, это хорошая причина для компиляции кода с несколькими компиляторами, чтобы получить больше проблем во время компиляции. –

4

Clang не может его поймать, по крайней мере, не как часть компиляции (я не проверял статический анализатор clang, и если он также не может, пожалуйста, сообщите об ошибке).

GCC решил, что это нормально испускать предупреждения от середины оптимизатора:

$ g++ -Waggressive-loop-optimizations a.cc 
$ g++ -Waggressive-loop-optimizations a.cc -O2 
a.cc: In function ‘int main()’: 
a.cc:6:5: warning: iteration 2147483647u invokes undefined behavior [-Waggressive-loop-optimizations] 
    for (int i(0); i != n; ++i) 
    ^
a.cc:6:5: note: containing loop 

Это на самом деле очень сложно и потенциально привередливы. Разработчики clang полагают, что изменение того, какие предупреждения вы испускаете на основе уровня оптимизации, - это плохое поведение, мы не думаем, что пользователи будут пропускать предупреждения при создании на -O0 или обнаруживать новые ошибки через несколько дней при создании сборки. Во-вторых, способ, которым проектируется оптимизатор, таков, что он хранит одно представление программы в любой момент времени и преобразует его от того, чтобы говорить одну вещь другому, не сохраняя историю следа того, что она сделала, в сравнении с исходным кодом. Это LLVM blog article рассказывает о проблеме. Предупреждения Клана строятся поверх АСТ AST Clang, которые имеют полное представление исходного исходного кода, включая шаблоны и истории макросов, поэтому мы всегда можем указать на правильный код и фильтровать такие свойства, как «был ли он аргументом шаблона».

Возможно, это будет возможно добавить к clang, я не нашел эффективный способ сделать это после 30 секунд размышлений об этом. Проблема в том, что мы готовы потратить гораздо больше времени на то, чтобы доказать, что в оптимизаторе, чем мы, как часть поколения предупреждения. Мы не хотим дважды оплачивать время компиляции. С другой стороны, статический анализатор не имеет этого ограничения и с радостью сделает очень дорогостоящую работу, чтобы найти ваши ошибки.

Наконец, как вы сформулировали свой вопрос, это звучит так, как будто вы думаете, что clang либо делает, либо не обнаруживает все неопределенное поведение во время компиляции. Мы эффективно ловим as much as we can и предоставляем динамические шашки для максимально возможного количества отдыха, но ни gcc, ни clang не обещают поймать все неопределенные действия либо во время компиляции, либо во время выполнения. Слишком много, и нет списка того, что все это (некоторые операции явно UB в стандарте, некоторые из них - UB просто потому, что стандарт не может определить, что такое поведение!).

+0

'Waggressive-loop-optimizations' действительно поистине здесь [вопрос] (http://stackoverflow.com/q/32506643/1708801), где структура кода имеет отношение к тому, получаем ли мы предупреждение или нет. –

+0

Это очень плохо. Если компилятор иногда может сказать мне, что у меня есть ошибка в моем коде, я бы хотел, чтобы он это сделал, даже если он не всегда может мне сказать. –

Смежные вопросы