It's an essential feature used in all sorts of everyday code.
C99 added printf conversion specifiers that are hidden behind macros, and idomatic usage of them relies on string catenation.
uint32_t x = 0;
printf("x = " PRIx32 "\n", x);
where PRIx32 might expand to "%lx" (if uint32_t is the same as unsigned long in that compiler).All sorts of C macrology relies on string catenation. Kernel print messages:
printk(KERN_EMERG "%s: temperature sensor indicates fire!", dev->name);
^ must not have comma hereAlthough I just had a (logging) use case in go where I missed cpp macros - wanted the log statement to get something from the file and just had to pass it in as another parameter.
If I have a uint32_t which needs printing I cast it to (unsigned long) and use %lu or %lx. This requires more typing in the argument list, but keeps the format string tidy. It's important for the format string to be tidy, because that's the reason of its existence: to clearly and concisely convey the shape of what is being printed.
That would be adding 2 pointers, and that's indeed illegal.
However, you can subtract them: “abc” - “def” . Now, the result is not a pointer any more, it's a ptrdiff_t (an integer type), so most compilers will warn if you try to assign that to a char *.
String catenation ("adding") by adjacency (no visible operator) is a thing; "add" doesn't imply that we are talking about a + operator:
$ awk 'BEGIN { x = "abc-" 2 + 2 "-def"; print x}'
abc-4-def execl("/bin/sh", "/bin/sh", "-c"
"echo foo", (char *) NULL);
Here we get one "-cecho foo" argument passed to the shell instead of two, so it can't work.Initializers are another example:
char *strArray[] = {
"how", "now"
"brown", "cow"
};
In non-variadic function and macro calls, you will most likely get an insufficient arguments error, unless another mistake compensates for that.