Избавление от #ifndef NDEBUG

В большинстве моих классов есть переменные отладки, поэтому они часто выглядят так:

class A
{
    // stuff
#ifndef NDEBUG
    int check = 0;
#endif
};

а методы могут выглядеть так:

for (/* big loop */) {
    // code
#ifndef NDEBUG
    check += x;
#endif
}

assert(check == 100);

Немногое уродливее, чем все эти #ifndef NDEBUG. К сожалению, ни один из известных мне компиляторов не может оптимизировать переменную check без этих #ifndefs (я не знаю, разрешено ли это вообще).

Итак, я попробовал чтобы найти решение, которое облегчило бы мою жизнь. Вот как это выглядит сейчас:

#ifndef NDEBUG

#define DEBUG_VAR(T) T

#else

template <typename T>
struct nullclass {
    inline void operator+=(const T&) const {}
    inline const nullclass<T>& operator+(const T&) const { return *this; }
    // more no-op operators...
};

#define DEBUG_VAR(T) nullclass<T>

#endif

Итак, в режиме отладки DEBUG_VAR (T) просто создает T. В противном случае он создает «нулевой класс» только без операций. И мой код будет выглядеть так:

class A {
   // stuff
   DEBUG_VAR(int) check;
};

Тогда я мог бы просто использовать check , как если бы это была обычная переменная! Отлично! Однако есть еще 2 проблемы, которые я не могу решить:

1 . Он работает только с int, float и т. Д.

«Нулевой класс» не имеет push_back () и т. Д. Ничего особенного. В любом случае, большинство переменных отладки - это целые числа.

2. «Нулевой класс» имеет ширину 1 символ !!

Каждый класс в C ++ имеет ширину не менее 1 символа. Таким образом, даже в режиме выпуска класс, который использует N отладочных переменных, будет по крайней мере на N символов больше. Это в моих глазах просто недопустимо. Это противоречит принципу нулевых накладных расходов, к которому я стремлюсь изо всех сил.

Итак, как мне решить эту вторую проблему? Можно ли вообще избавиться от #ifndef NDEBUG, не повредив производительность в режиме без отладки? Я принимаю любое хорошее решение, даже если это ваше самое мрачное волшебство на C ++ или C ++ 0x.

9
задан Migi 16 February 2011 в 13:36
поделиться