Удобные стратегии проверки утверждений - PullRequest
1 голос
/ 19 сентября 2009

Некоторые утверждения являются дорогостоящими, некоторые лучше отключить в рабочем коде. По крайней мере, не ясно, что утверждения должны быть всегда включены.

В моем приложении я хотел бы иметь возможность включать / выключать часть утверждений для каждого файла или для каждого класса.

Как это сделать в C ++?

Ответы [ 3 ]

2 голосов
/ 19 сентября 2009

Для деактивации утверждений по всему модулю я бы использовал:

#if defined(assert)
#  undef assert
#  define assert(x) ((void)0)
#endif

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

#if defined(_NO_ASSERTS)
#  define myAssert(x) ((void)0)
#else
#  define myAssert(x) assert(x)
#endif

Для деактивации в классе я бы использовал статический член класса const или перечисление в классе в сочетании с пользовательским макросом:

#define myAssert(x) do { if(_CLASS_ASSERT) { assert(x); } } while(0)

class AssertOff
{
  enum { _CLASS_ASSERT = 0 }
}

С помощью перечислений и статических констант все современные компиляторы должны оптимизировать if(_CLASS_ASSERT) {}.

1 голос
/ 19 сентября 2009

Для кодирования с утверждениями учитывается хороший стиль кодирования.

Что касается времени выполнения включение / выключение Вы можете сделать это с помощью логической переменной. Например, в вашем коде вы можете сделать следующее:

Определите переменную, которая будет использоваться, чтобы указать, включены ли утверждения в глобальном пространстве имен (например, из функции main () в том же файле).

bool  turnOnAssertions;

Определите переменную, как написано ниже, в других файлах, где вы хотите включить / выключить свои утверждения:

extern bool turnOnAssertions; 

Итак, манипулируя переменной turnOnAssertions с помощью пользовательского интерфейса и записывая

if(turnOnAssertions)
assert(…);

Вы можете включить / выключить некоторые из ваших утверждений!

Что касается времени компиляции , вы должны сделать следующее:

Для вашего компилятора вы должны указать флаг типа -DASSERTIONSON (-Dflag_name [имя флага, вы можете установить все, что захотите])

#ifdef ASSERTIONSON 
bool turnOnAssertions = true;
#else
bool turnOnAssertions = false;
#endif

И просто используйте переменную.

Удачи!

0 голосов
/ 19 сентября 2009

Чтобы отключить утверждения для файла C ++, вы можете выполнить одно из следующих действий:

  • Определите константу NDEBUG в верхней части исходного файла.
  • Добавьте -DNDEBUG к параметрам компиляции для исходного файла.

Большинство IDE и / или инфраструктуры сборки позволяют вам указывать параметры сборки для каждого файла, так что это простое решение.

Отключить утверждения для каждого класса сложнее, когда несколько классов смешаны в одном исходном файле или у вас много встроенных функций в заголовочных файлах. Можно конечно #define NDEBUG и #undef NDEBUG в соответствующих местах.

Поскольку некоторые IDE ожидают, что смогут установить NDEBUG для не отладочных сборок, вы можете сделать его более расширяемым, выбрав собственное имя макроса, например DISABLE_ASSERT. Затем включите код, подобный следующему, в общий заголовочный файл (который предварительно не скомпилирован):

 #ifdef DISABLE_ASSERT
 #define NDEBUG
 #endif
...