Am I misunderstanding assert() usage?

2019-02-11 14:13发布

I was taking a look at the assert() reference page and I got stuck while I read the given example:

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

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

  fclose (datafile);

  return 0;
}

In this example, assert is used to abort the program execution if datafile compares equal to 0, which happens when the previous call to fopen was not successful.

I totally agree that if fopen() fails, assert() will abort execution. However I'm concerned about the rightness of this example:

In my opinion assert() is there to detect cases that can't normally happen (like passing a NULL pointer to a function whose documentation states it is forbidden).

In this example, failing to open a file is not something that can't normally happen. In fact, I can see dozens of reasons why this would fail. The file couldn't exist, the program could run without required privileges, and so on.

I would rather have done something like:

/* 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;
}

Is my understanding of how assert() should be used incorrect ?


EDIT AND GOOD NEWS !

It seems the referred site is ruled by rigorous people. Here is the mail I got back from one of the site maintainer:

Hi Julien, I have to agree, the example code was poorly chosen. It has now been just rewritten to something more appropriate.

Many thanks for pointing this out, and sorry for any inconveniences this may have caused to you.

Best regards,

And the updated example:

/* 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;
}

Glad to see that some people do their work well on the Internet ! ;)

标签: c++ c assert
3条回答
Evening l夕情丶
2楼-- · 2019-02-11 14:34

You are right indeed. As other people have already pointed out, assert() will be more than likely compiled out in the release build (I've seen people force the asserts to be left in for the release build).

I just wanted to add a horror story related to this question that I've seen on a code-base:

assert(do_something() == NO_ERR);

Some people should not be allowed to use a keyboard.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-02-11 14:35

You're perfectly right sir. This is a poor usage of assert.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-02-11 14:39

Minor notification: it would be better if you write..

FILE * datafile = NULL;

Also, assert only works in debug mode... so your method is better.

查看更多
登录 后发表回答