I would like a static assertion to be sure that a given expression is a string literal. I tried this:
#define SAME_TYPES(x, y) __builtin_types_compatible_p(typeof(x), typeof(y))
#define IS_ARRAY(x) !SAME_TYPES((x), &(x)[0])
#define IS_COMPILE_TIME_STR(x) IS_ARRAY(x) && #x[0] == '"'
#define ASSERT_COMPILE_TIME_STR(x) static_assert(IS_COMPILE_TIME_STR(x), "Only static allocated compile time strings are allowed, but got this: " #x)
/*
* ASSERT_COMPILE_TIME_STR("hey"); <-- this is fine
* ASSERT_COMPILE_TIME_STR(1234); <-- this should fail
*/
Unfortunately, ASSERT_COMPILE_TIME_STR does not work, because #x[0] == '"' does not seem to be a compile-time-constant.
Is there some other way to achieve this? It just has to compile with gcc, so any kind of extensions are fine:)
Thanks a lot
C allows consecutive string constants which the compiler combines into a single constant. You can exploit this by attempting to put a string constant in line with the expression in question.
A few notes about the above:
(x)on the left side of the comma operator helps to catch certain types of non-expressions such as0+voidcast on both the left side of the comma operator and the full expression prevent warnings about an expression with no effect.The above accepts this with no warning or error:
While generating one or more errors with these:
This isn't perfect, but should catch most cases.