Предотвращение предупреждений о неиспользуемых переменных при использовании assert () в сборке выпуска - PullRequest
53 голосов
/ 22 апреля 2009

Иногда локальная переменная используется с единственной целью проверки ее в assert (), например, -

int Result = Func();
assert( Result == 1 );

При компиляции кода в сборке Release, assert () обычно отключаются, поэтому этот код может выдавать предупреждение о том, что Result установлен, но никогда не читается.

Возможный обходной путь -

int Result = Func();
if ( Result == 1 )
{
    assert( 0 );
}

Но это требует слишком большого набора текста, это не просто на глаз и заставляет условие всегда проверяться (да, компилятор может оптимизировать проверку, но все же).

Я ищу альтернативный способ выражения этого assert () таким образом, чтобы не вызывать предупреждение, но при этом быть простым в использовании и избегать изменения семантики assert ().

(отключение предупреждения с помощью #pragma в этой области кода не вариант, и снижение уровней предупреждения, чтобы оно исчезло, тоже не вариант ...).

Ответы [ 16 ]

1 голос
/ 28 августа 2012

Конечно, вы используете макрос для управления вашим утверждением, например, "_ASSERT". Итак, вы можете сделать это:

#ifdef _ASSERT 
int Result =
#endif /*_ASSERT */
Func();
assert(Result == 1);
1 голос
/ 22 апреля 2009

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

Кроме того, все равно имеет смысл быть внутри функции, потому что она создает автономный блок, который имеет свои СОБСТВЕННЫЕ предварительные и дополнительные условия.

Скорее всего, если функция возвращает значение, вы все равно должны выполнить какую-то проверку ошибок в режиме сброса для этого возвращаемого значения. Так что это не должна быть переменная без ссылки для начала.

Редактировать, но в этом случае условие публикации должно быть X (см. Комментарии):

Я категорически не согласен с этим моментом: нужно уметь определять состояние поста по входным параметрам и, если это функция-член, любое состояние объекта. Если глобальная переменная изменяет выходные данные функции, то функция должна быть реструктурирована.

0 голосов
/ 19 февраля 2018
// Value is always computed.  We also call assert(value) if assertions are
// enabled.  Value is discarded either way.  You do not get a warning either
// way.  This is useful when (a) a function has a side effect (b) the function
// returns true on success, and (c) failure seems unlikely, but we still want
// to check sometimes.
template < class T >
void assertTrue(T const &value)
{
  assert(value);
}

template < class T >
void assertFalse(T const &value)
{ 
  assert(!value);
}
0 голосов
/ 05 октября 2014

Если этот код находится внутри функции, действуйте и верните результат:

bool bigPicture() {

   //Check the results
   bool success = 1 != Func();
   assert(success == NO, "Bad times");

   //Success is given, so...
   actOnIt();

   //and
   return success;
}
0 голосов
/ 22 апреля 2009

Я бы использовал следующее:

#ifdef _DEBUG
#define ASSERT(FUNC, CHECK) assert(FUNC == CHECK)
#else
#define ASSERT(FUNC, CHECK)
#endif

...

ASSERT(Func(), 1);

Таким образом, для сборки релиза компилятору даже не нужно создавать никакого кода для assert.

0 голосов
/ 22 апреля 2009
int Result = Func();
assert( Result == 1 );
Result;

Это заставит компилятор перестать жаловаться на то, что Result не используется.

Но вам следует подумать об использовании версии assert, которая делает что-то полезное во время выполнения, например, описательные ошибки в журнале для файла, который можно извлечь из производственной среды.

...