gpt4 book ai didi

c - 有效地 "Wrapping"C 中的常量字符串

转载 作者:行者123 更新时间:2023-11-30 15:51:57 28 4
gpt4 key购买 nike

我目前正在用 C 语言编写一个解析器,设计它时我需要的东西之一是一个可变字符串“类”(一组对表示实例的不透明结构进行操作的函数),我将其称为 my_string。 string 类的实例只不过是包装 char * 以及一些元数据的结构。

但是,常量字符串会出现问题。例如,我有几个返回 my_string * 指针的方法,但有时我想返回一个常量字符串。考虑这个人为的伪代码:

my_string *element_get_data(my_element *el)
{
if (element_has_character_data(el))
return element_get_character_data(el); /* returns a (my_string *) */
else
return my_string_constant("#data"); /* ditto */
}

…在某些情况下,我想获取预构建的 my_string 实例,但在其他情况下,我只想返回包裹在 my_string 中的字符串“#data” > 结构。

此代码的问题在于,每次调用 element_get_data(...) 时,它都会创建一个新的(堆分配的)my_string 实例。 C 常量字符串具有良好的语义,因为它们静态分配在程序的 DATA 部分中,因此每次遇到常量字符串时,该字符串的地址始终相同。

因此,让多个不同的 my_string 实例都指向完全相同的 char * 似乎很愚蠢。消除重复的有效方法是什么?我应该保留 const char * -> my_string * 映射的哈希表吗?或者有没有办法使用与 C 常量字符串类似的语义?在 Mac 上,Core Foundation 设法使用 CFSTR(...) 宏来做到这一点。

对我来说理想的解决方案是以某种方式制作一个像 my_string_constant(...) 这样的宏,将 my_string 结构存储在程序的 DATA 部分,因此它也可以是常量。这样的事可能吗?

最佳答案

当我写这个问题时(或者更确切地说,几乎是在我写完之后),我以 GNUStep's implementation of Core Foundation's CFSTR() macro 的形式找到了我的问题的答案。 。我的类似实现如下所示:

#define MY_STR(str) ({\
static struct { const char *buffer; my_bool shouldFree; my_bool mutable; my_bool constant; } s = {NULL, MY_FALSE, MY_FALSE, MY_TRUE};\
s.buffer = str;\
(my_string *)&s;\
})

这样做的原因是因为代码块在编译时被内联,这意味着它创建了一个相对于本地范围的静态分配的结构。因此,如果(例如)一个函数包含 MY_STR("Hello, world!")被多次调用,将始终返回相同的静态分配结构,从而产生我们期望的行为。

这个概念可以轻松扩展到字符串之类的事物之外,从而使您可以轻松创建自己的静态分配对象类型。整洁!

关于c - 有效地 "Wrapping"C 中的常量字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14765880/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com