2011-12-20 6 views
4

Я хотел бы добавить CXXFLAG в мои системы сборки, которые заставляют всю базу кода быть четко определенными. Поэтому каждый кусок кода, который статически демонстрирует неопределенное поведение, должен быть отклонен компилятором.Как заставить g ++ отказаться от кода, который демонстрирует неопределенное поведение?

Например reinterpret_cast<A*>(someIntPtr)->aMember без какого-либо контекста выполнения не определено (а), в то время как int i = bar(); i /= i; может привести к непредсказуемому поведению (б) в зависимости от оценки во время выполнения bar() (которые могут возвращать ноль).
Я ожидаю, что (а) случаи будут пойманы, а не обязательно (b).

+1

Может быть, это может поймать 'я/= i' тоже, так как если это не определено поведение, это просто глупо способ сказать' я = 1'. –

+1

Ответы на [Реализация C++, которая обнаруживает неопределенное поведение?] (Http://stackoverflow.com/q/7237963/2509), адрес, который можно сделать с помощью g ++ в этом направлении. – dmckee

+0

@Benjamin Lindley: 'i/i' не является silliy способом сказать' 1', потому что 'i/i' не определено iff' i == 0'. Во всех остальных случаях вы правы, это '1'. – bitmask

ответ

7

Я не уверен, что ваша цель является вычислительной осуществимостью.

Однако, вы получите умеренно близкое расстояние с -Wall -Wextra -Werror; посмотрите другие варианты предупреждений, чтобы узнать, что еще вы хотите включить.

+0

Как сказал @Kerrek, компилятор пропустит многие случаи, но +1 к Джонатану за то, что он конструктивен и дает лучшие доступные варианты. Я также запускаю программу с valgrind, чтобы выявлять любые проблемы с доступом к памяти, которые втекают в окончательный исполняемый файл. – ams

1

Вы можете использовать инструменты для анализа статического кода, похожие на классические lint. Возможно, у вас уже есть cppcheck.

1

Вы не можете, и вы не должны полагаться на компилятор, чтобы указать UB для вас.

Вы лучше всего использовать -Werror, чтобы вызвать все предупреждения стать ошибки, и then enable a great deal of warnings.

6

невозможно. Существует множество примеров UB, которые не поддаются обнаружению. Это, возможно, причина , почему они UB, точно , потому что невозможно поймать эти проблемы во время компиляции.

Некоторые примеры:

  • int n = 0; std::cin >> n; ++n; Подпись переполнения UB. (Пример значения -зависимой UB.)

  • double d = std::sin(some_user_value); int n = d; УБ, если d не может быть представлена ​​как int. (То же.)

  • скомпилировать множественные единицы перевода с различными определениями классов, видимыми каждому. (Пример UB из-за ограничений модели компиляции.)

  • любое состояние гонки по определению UB. (Пример UB.)

  • неправильное использование вариационных функций. (Пример UB благодаря системе типа.)

+0

Конечно, он вообще неразрешимый (проблема с остановкой). Вот почему я добавил второй абзац; Обнаружить все статические случаи. – bitmask

+0

"' int n; std :: cin >> n; ++ n; '" Без проверки ошибок существует потенциал для UB здесь, если только не предполагается, что операция ввода завершается успешно. – curiousguy

+0

Опять же, проверка ошибок отсутствует, что является ошибкой программирования и может вызвать UB, если только вы не можете предположить, что форматированная операция чтения успешно завершена. – curiousguy

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

  • Нет связанных вопросов^_^