assert() with message

46,868

Solution 1

Use -Wno-unused-value to stop the warning; (the option -Wall includes -Wunused-value).

I think even better is to use another method, like

assert(condition && "message");

Solution 2

Try:

#define assert__(x) for ( ; !(x) ; assert(x) )

use as such:

assert__(x) {
    printf("assertion will fail\n"); 
}

Will execute the block only when assert fails.

IMPORTANT NOTE: This method will evaluate expression x twice, in case x evaluates to false! (First time, when the for loop is checking its condition; second time, when the assert is evaluating the passed expression!)

Solution 3

If you want to pass a formatted message, you could use the following macros:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>

#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_error(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define assertf(A, M, ...) if(!(A)) {log_error(M, ##__VA_ARGS__); assert(A); }

Then use it like printf:

// With no args
assertf(self != NULL,"[Server] Failed to create server.");

// With formatting args
assertf((self->socket = u_open(self->port)) != -1,"[Server] Failed to bind to port %i:",self->port);
// etc...

Output:

[ERROR] (../src/webserver.c:180: errno: Address already in use) [Server] Failed to bind to port 8080: webserver: ../src/webserver.c:180: server_run: Assertion `(self->socket = u_open(self->port)) != -1' failed.

Based on http://c.learncodethehardway.org/book/ex20.html

Solution 4

By tradition, (void) communicates to the compiler that you are knowingly ignoring an expression:

/* picard.c, TNG S6E11. */
#define assertmsg(x, msg) assert(((void) msg, x))
assertmsg(2+2==5, "There! are! four! lights!");

Solution 5

For unexpected default case of a switch, an options is

assert(!"message");
Share:
46,868
Alexandru
Author by

Alexandru

I need another badge!

Updated on May 27, 2021

Comments

  • Alexandru
    Alexandru almost 3 years

    I saw somewhere assert used with a message in the following way:

    assert(("message", condition));
    

    This seems to work great, except that gcc throws the following warning:

    warning: left-hand operand of comma expression has no effect
    

    How can I stop the warning?

  • pmg
    pmg about 13 years
    The inner parenthesis make it ok: assert( ("message", condition) ); This is C: no overloading.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 11 years
    Don't see what relevance a C++ website has to a C question.
  • Julien
    Julien over 11 years
    Nice one, I usually do assert(condition /* message */).
  • Samaursa
    Samaursa about 11 years
    This sometimes gives "Conditional expression is constant" warning in Visual Studio. Any ideas on how to remove the warning without suppressing it?
  • pmg
    pmg about 11 years
    @Samaursa: you probably have an issue with plain condition. Does the compiler also warn with just assert(condition);?
  • Samaursa
    Samaursa about 11 years
    It does not. The interesting thing is that OP's original problem code is the solution to VS's warnings! assert((Msg, Cond)); works without warnings on VS 2008.
  • Kevin Cox
    Kevin Cox almost 10 years
    The nice thing about this is that you can omit the message if you want by using assert__(foo); and the semicolon will end the block.
  • chad
    chad over 8 years
    This, unfortunately, isn't portable. C99 requires that you use at least one of the optional arguments in a variadic macro (e.g this: assertf(x == y, "x does not equal y") violates the standard. This is easily rectified via assertf(x == y, "%s", "x does not equal y") however). It also relies on the gcc extension ##__VA_ARGS__ which isn't necessarily a bad thing, but it does make it less portable
  • Oleg
    Oleg over 8 years
    Such implementation will not work if (x) returns true only once: string("a") a; assert__(a.append("b") == "ab") { ... }
  • Caridorc
    Caridorc over 8 years
    Why for and not if?
  • ahogen
    ahogen over 4 years
    assert((<cond>) && "msg"); causes CppCheck (v1.90) to generate an "incorrectStringBooleanError" warning.
  • VLL
    VLL almost 3 years
    This seems to be always false. Where is the condition that is being tested?
  • VLL
    VLL almost 3 years
    This does not seem to work in GCC. Failing assert stops the program execution and printf is not called.
  • Flaviu
    Flaviu almost 3 years
    This useful for unexpected default case of a switch.
  • john-g
    john-g almost 3 years
    That, while true, doesn't have anything to do with the original question.
  • Jack G
    Jack G over 2 years
    @vil It is not possible for assert to stop the program before printf because assert is not called until after printf.