7

Обычно, когда я стираю элемент из набора, я хочу утверждать, что это было на самом деле стерта: т.е.утверждают возвращаемого значения, но работать в любом случае

assert(s.erase(e)); 

но тогда элемент не получает стирается, когда установлен NDEBUG. Но если я пишу

bool removed = s.erase(e); 
assert(removed); 

компилятор жалуется, что «удаленный» не используется, когда установлен NDEBUG.

Как я могу это сделать правильно?


Я в конечном итоге просто создать метод полезности:

inline void run_and_assert(bool b) { 
    assert(b); 
} 

теперь я могу сказать

run_and_assert(s.erase(e)); 

Существуют ли какие-либо недостатки в этом? Мне кажется более простым, чем решение luiscubal.

+0

, какой компилятор? –

+0

Я использую g ++. Но это то, что должен делать хороший компилятор, верно? – dspyz

+3

Многие компиляторы предоставляют функцию 'verify()' function/macro, которая делает то, что вы хотите. –

ответ

0

Я написал мой как предложение luiscubal, за исключением вместо уродливых # Определяет, я сделал короткий метод инлайн:

inline void assert_always_execute(bool x) { 
    assert(x); 
} 
+0

... который все еще жалуется на 'неиспользованный параметр 'x'' при компиляции с' NDEBUG', и таким образом решает проблему, как? – DevSolar

8

Первый пример неверен, потому что выражение assert будет удалено при определении NDEBUG, поэтому s.erase(e) не будет вызываться вообще.

Аргумент assert НИКОГДА не должен иметь побочных эффектов.

Второй подход лучше, хотя предупреждение действительно может быть раздражающим, но there are ways to silence the warning.

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

#ifdef NDEBUG 
#define assert_always_execute(x) (x) 
#else 
#define assert_always_execute(x) assert(x) 
#endif 
Смежные вопросы