Подтвердить что ты не робот

Не понимаю ли я утверждение assert()?

Я смотрел справочную страницу assert(), и я застрял, когда прочитал данный пример:

/* assert example */
#include <stdio.h>
#include <assert.h>

int main ()
{
  FILE * datafile;
  datafile=fopen ("file.dat","r");
  assert (datafile);

  fclose (datafile);

  return 0;
}

В этом примере assert используется для прерывания выполнения программы, если файл данных сравнивается с 0, что происходит, когда предыдущий вызов fopen не был успешным.

Я полностью согласен, что если fopen() не удается, assert() отменяет выполнение. Однако я обеспокоен правильностью этого примера:

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

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

Я бы скорее сделал что-то вроде:

/* not longer an assert example */
#include <stdio.h>
#include <assert.h>

int main ()
{
  FILE * datafile;
  datafile=fopen ("file.dat","r");

  if (datafile != NULL)
  {
    // Do something, whatever.
    fclose (datafile);
  } else
  {
    // Report the error somehow.
  }

  return 0;
}

Является ли мое понимание того, как assert() следует использовать неправильно?


ИЗМЕНИТЬ И ХОРОШИЕ НОВОСТИ!

Кажется, что упомянутым сайтом управляют строгие люди. Вот почта, которую я получил от одного из сопровождающих сайта:

Привет, Жюльен, я должен согласиться, пример кода был плохо выбран. В нем есть теперь просто переписано чему-то более подходящим.

Большое спасибо за указав это, и извините за любые неудобства, которые это могло вызвать вы.

С уважением,

И обновленный пример:

/* assert example */
#include <stdio.h>
#include <assert.h>

void print_number(int* myInt) {
  assert (myInt!=NULL);
  printf ("%d\n",*myInt);
}

int main ()
{
  int a=10;
  int * b = NULL;
  int * c = NULL;

  b=&a;

  print_number (b);
  print_number (c);

  return 0;
}

Рад видеть, что некоторые люди хорошо работают в Интернете!;)

4b9b3361

Ответ 1

Ты совершенно прав, сэр. Это плохое использование assert.

Ответ 2

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

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

assert(do_something() == NO_ERR);

Некоторым людям не разрешается использовать клавиатуру.

Ответ 3

Незначительное уведомление: было бы лучше, если вы напишете.

FILE * datafile = NULL;

Кроме того, утверждение работает только в режиме отладки... так что ваш метод лучше.