assert() with message

CGccCompiler WarningsAssert

C Problem Overview


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?

C Solutions


Solution 1 - C

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 - C

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 - C

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 - C

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 - C

A function that takes const char* and returns true would probably save you from all sorts of warnings:

#include <assert.h>

int always_true(const char *msg) {
    return 1;
}

#define assert_msg(expr, msg) assert((expr) && always_true(msg))

Solution 6 - C

For unexpected default case of a switch, an options is

assert(!"message");

Solution 7 - C

In my case, I changed @pmg's answer to be able to control the output. The (... && "message") didn't work for me.

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

#define __DEBUG__ 1

assert ((1 == 1) && 
       (__DEBUG__ && printf("  - debug: check, ok.\n")) || !__DEBUG__);

Solution 8 - C

You could write your own macro that provides the same usage of _Static_assert(expr, msg):

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>


/*
 * void	assert_msg(bool expr, const char *msg);
 */
#if !defined(NDEBUG)
#define assert_msg(expr, msg)	do					\
{													\
		const bool	e_ = expr;						\
													\
		if (!e_) {									\
				fputs(msg, stderr);					\
				fputc('\n', stderr);				\
				assert(e_);							\
		}											\
} while (0)
#else
#define assert_msg(expr, msg)	do					\
{													\
													\
		if (!(expr))								\
				warn_bug(msg);						\
} while (0)
#endif

I also have a macro warn_bug() that prints the name of the program, the file, the line, the function, the errno value and string, and a user message, even if asserts are disabled. The reason behind it is that it won't break the program, but it will warn that a bug will probably be present. You could just define assert_msg to be empty if defined(NDEBUG), though.

Solution 9 - C

According to following link http://www.cplusplus.com/reference/clibrary/cassert/assert/

assert is expecting only expression. May be you are using some overloaded function.

According to this, only expression is allowed and thus you are getting this warning.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexandruView Question on Stackoverflow
Solution 1 - CpmgView Answer on Stackoverflow
Solution 2 - CbugfeederView Answer on Stackoverflow
Solution 3 - CfrmdstryrView Answer on Stackoverflow
Solution 4 - CMingye WangView Answer on Stackoverflow
Solution 5 - CJiaHao XuView Answer on Stackoverflow
Solution 6 - CFlaviuView Answer on Stackoverflow
Solution 7 - Cuser9869932View Answer on Stackoverflow
Solution 8 - CalxView Answer on Stackoverflow
Solution 9 - CDhirajView Answer on Stackoverflow