Home > database >  Why does using C's assert function skip evaluation of a conditional that comes before it?
Why does using C's assert function skip evaluation of a conditional that comes before it?

Time:12-03

I was using C's assert.h assert function in a method similar to this:

int x = 3;

if (x == 3)
    printf("x is 3 ✅");

assert(x != 3);

When running it, I found out that the if statement is skipped entirely, and the program terminates when it reaches the assert statement. Needless to say, this caused a couple of extremely nasty bugs in my program before I found the culprit. What could be the cause of this? Why is the conditional being skipped entirely? If it isn't being skipped, then why is the code inside not being executed? I set up an online example here.

CodePudding user response:

The if statement is not skipped.

When assert is executed, it is not considered a "clean" program termination. Therefore, I/O buffers are not flushed. Try adding a fflush() call to explicitly flush stdout's buffer:

int x = 3;

if (x == 3)
{
    printf("x is 3 ✅");
    fflush(stdout);
}

assert(x != 3);

Here are the relevant paragraphs from the C17 standard (italic emphasis mine):

7.2.1.1

The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function — the latter are respectively the values of the preprocessing macros __FILE__ and __LINE__ and of the identifier __func__) on the standard error stream in an implementation-defined format. It then calls the abort function.

7.22.4.1

The abort function causes abnormal program termination to occur, unless the signal SIGABRT is being caught and the signal handler does not return. Whether open streams with unwritten buffered data are flushed, open streams are closed, or temporary files are removed is implementation-defined.

  •  Tags:  
  • c
  • Related