Adjacent string literals are concatenated, and this is useful two ways: macros which combine strings and visualizing multi-line string literals such as you have above. Compare how that code would look otherwise:
char const help_message[] = "Usage: %s [options] files ...\n\nOptions include:\n --verbose -v Be verbose\n --help -h Print this help message\n --output -o Specify output file\n\n";
Imagine trying to maintain that instead. In addition, if you use a multi-line string literal, you have to either escape newlines or deal with whatever the source code uses, which may not be '\n', and you'll have to watch your indentation carefully. All of which makes the code in your example better.
Here's an example of the macro case:
#define STRINGIZE_(v) #v
#define STRINGIZE(v) STRINGIZE_(v)
#define LOCATION __FILE__ ":" STRINGIZE(__LINE__)
#define MY_ASSERT(expr) do { \
if (!(expr)) \
some_function(LOCATION ": assertion failed in " \
__PRETTY_FUNCTION__ ": " #expr); \
} while (0)
(There are alternatives to this, such as passing separate parameters, and using the GCC-specific __PRETTY_FUNCTION__ like this is deprecated too, but the rest is handy and this is a decent "real" example, IMHO.)
Other issues brought up in that code to be aware of:
- the single
# is the preprocessor stringize operator (## is the other special preprocessor operator, for token pasting)
- without the second stringize macro, you'll get
"filename.c:__LINE__"
- using do-while doesn't break if-else and requires the macro to be used as a statement rather than an expression
- preventing use as an expression isn't always helpful, but it is what you want for assert-like macros
Breaking if-else example:
if (cond) MY_ASSERT(blah);
else other();
Expands to:
if (cond) do { ... } while(0);
else other();
Instead of:
if (cond) if (...) ...;
else other();
Which is the incorrect and surprising:
if (cond) {
if (...) {
...;
}
else {
other();
}
}