I don't know of a way to return true or false. But usually you just want to use the string, and assert that it's a string literal (at least this is what I needed in some code). I developed a macro that returns the string value if it is a string literal, but breaks the compilation if it is not:
#define string_literal(s) ("" s "")
This is quite safe against accidental misuses. One can still break it (thanks to @chqrlie https://stackoverflow.com/users/4593267/chqrlie for showing the way to break it): string_literal(""[0] + p + *"")
, but that code looks suspicious anyway, so I wouldn't call it unsafe.
You can make it more robust, at the expense of some readability:
#define NELEMS(a) (sizeof(a) / sizeof((a)[0]))
#define string_literal(s) ("" s "" + 0 * NELEMS(s))
This will warn about non-arrays in some recent compilers. GCC would warn with -Wsizeof-pointer-div
. In C2y, there will be a new keyword that will make it a constraint violation, which will make it more robust. See https://thephd.dev/the-big-array-size-survey-for-c.
Actually, I only used this for calling strdupa(3) safely. Thus, I skipped the string_literal()
macro entirely, and wrote a wrapper macro around strdupa(3) that made sure that it was always called with a string literal as argument:
#define STRDUPA(s) strdupa("" s "")
I considered implementing it in the following way for more robustness, but for simplicity and readability reasons, I have stayed with the implementation above. Anyway, here it is:
#define STRDUPA(s) strndupa("" s "", NITEMS(s))