c# C:Assert表达式是字符串文字

uqzxnwby  于 2023-06-27  发布在  C#
关注(0)|答案(1)|浏览(261)

我希望一个静态Assert能确保给定的表达式是字符串文字。我试过这个:

#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
 */

不幸的是,ASSERT_COMPILE_TIME_STR不起作用,因为#x[0] == '"'似乎不是一个编译时常数。
有没有其他的方法来实现这一点?它只需要用gcc编译,所以任何类型的扩展都可以:)
多谢了

gz5pxeao

gz5pxeao1#

C允许连续的字符串常量,编译器将其组合成一个常量.您可以通过尝试将一个字符串常量与所讨论的表达式对齐来利用此漏洞。

#include <stdio.h>

#define IS_STR_CONT(x) (void)(x"")

int main()
{
    IS_STR_CONT("hello");
    IS_STR_CONT(123);
    return 0;
}

编译器输出:

x1.c: In function ‘main’:
x1.c:3:32: error: expected ‘)’ before string constant
 #define IS_STR_CONT(x) (void)(x"")
                                ^
x1.c:8:5: note: in expansion of macro ‘IS_STR_CONT’
     IS_STR_CONT(123);
     ^

请注意,上面的表达式被强制转换为void,以防止有关表达式无效的警告。

相关问题