Take the 2-minute tour ×

In a project of mine (which for technical reasons must not depend on any external libraries or third-party sources) I have set up the following test.h:

static int rc = 0;
#define TESTCASE( x ) if ( x ) {} \
                      else \
                      { \
                          rc += 1; \
                          printf( "FAILED: " __FILE__ ", line %d - " #x "\n", __LINE__ ); \

This works fine most of the time - if the testcase evaluates to true, nothing happens. If the testcase evaluates to false, the testcase is printed including file name and line number.

However, when the testcase contains a string literal, the printf() in the TESTCASE macro insists on interpreting the string literal as part of the format string (which proved fatal for a certain testcase).

Now I am pondering various approaches to get the printf() to print whatever is in x (the testcase) verbatim, but I've come up empty. The closest thing was to use %c to print a fixed numbers of characters, and pass the textcase (#x) as parameter to printf() - but I couldn't figure out how to determine the size of #x, especially if it contains zero bytes (which rules out any use of strlen()).

Confused, and at a loss. Help?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

what about using %s as a format then passing the stringified test case as a parameter, like you did for the line number ?

printf( "FAILED: %s, line %d - %s\n", __FILE__, __LINE__, #x );

the # convert the argument to a properly double-quote delimited string, so nothing prevents you from passing this string as an argument to printf...

(you should never use any value that is not hardcoded as a format string for printf: that's raising hell most of the time)

share|improve this answer
A good first appriach, but what if the string literal in #x contains zero bytes? –  DevSolar Jun 24 '10 at 9:36
I don't think this is possible: a zero byte has no representation, it is not valid in a C source file and thus cannot appear in your test case. (or the definition of the TEST_CASE macro in your question is wrong) remember that the # preprocessor operator is a stringizer, it converts abc appearing literally in the macro argument by "abc". –  Adrien Plisson Jun 24 '10 at 9:48
And here I was halfway through typing 'hey, I could write "\0" into a string literal anytime' when I realized that '\0' is the representation of a zero byte, not the thing itself. AAaaargh... half my brain must have been asleep. You are absolutely right, of course. –  DevSolar Jun 24 '10 at 9:51

Your Answer


