我有一个基本的字符串结构:
typedef struct String {
size_t size;
union {
char *ptr, buf[sizeof(char *)];
};
} String;
我们的想法是能够从String
中提取char *
,如下所示:
extern String string;
char *str = string.size >= sizeof(char *) ? string.ptr : string.buf;
我有个问题如果我有一个const
static
/global String
结构体,必须在编译时初始化,该怎么办?如果我不想硬编码char *
是给定大小的假设,那会怎么样?
static const String string = {
sizeof(CONSTANT_STRING)-1,
#if sizeof(CONSTANT_STRING) > sizeof(char *)
.name
#else
.buf
#endif
= CONSTANT_STRING
但是我们知道sizeof()
happens after preprocess time so cannot be used in an #if
。
如何在编译时有条件地将字符串的一个成员或另一个成员赋给给定的值,以便得到的表达式是编译时常量?
2条答案
按热度按时间tkclm6bt1#
是的,这是可以做到的,但我不得不重新考虑
String
结构。我可以有一个命名的union成员,并使用?:
操作符有条件地将其初始化为不同的复合文字,而不是使用一个未命名的嵌套联合:然而,为了使复合字面值被认为是编译时常量,要么它必须在全局范围内,要么我必须使用C23并将它们指定为
constexpr
和/或将它们的存储类指定为static
。pnwntuvh2#
我想补充的是,
struct
中的空间比实际使用的空间要大,因为1-8之间的数值不需要size_t
类型。下面这个不完整的例子在64位系统上使用时,会为你的小字符串优化增加7个字节的空间:
这里有一个关于“野生”的例子。
facil.io C STL String模块有更好的优化,但这是来自CLI模块,它显示了这种方法的工作。它是为64位系统设计的,可能会在32位系统上增加额外的4字节开销(但这4个字节将被短字符串使用):