утверждать возвращаемое значение, но работать в любом случае

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

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));

Есть ли у этого недостатки? Мне это кажется проще, чем решение Луискубала


person dspyz    schedule 17.12.2013    source источник
comment
Я использую g ++. Но это то, что должен делать хороший компилятор, верно?   -  person dspyz    schedule 18.12.2013
comment
Многие компиляторы предоставляют verify() функцию / макрос, которые делают то, что вы хотите.   -  person Jonathan Wood    schedule 18.12.2013


Ответы (2)


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

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

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

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

#ifdef NDEBUG
#define assert_always_execute(x) (x)
#else
#define assert_always_execute(x) assert(x)
#endif
person luiscubal    schedule 17.12.2013

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

inline void assert_always_execute(bool x) {
    assert(x);
}
person dspyz    schedule 02.02.2014
comment
... который все еще жалуется на unused parameter 'x' при компиляции с NDEBUG, и, таким образом, решает проблему, как? - person DevSolar; 28.05.2015