gpt4 book ai didi

c - 如何在 rodata 中初始化灵活数组并创建指向它的指针?

转载 作者:太空狗 更新时间:2023-10-29 17:04:18 27 4
gpt4 key购买 nike

C语言中的代码

char *c = "Hello world!";

在 rodata 中存储 Hello world!\0 并使用指向它的指针初始化 c。我怎样才能用字符串以外的东西来做到这一点?

具体来说,我正在尝试定义我自己的字符串类型

typedef struct {
size_t Length;
char Data[];
} PascalString;

然后想要某种宏以便我可以说

const PascalString *c2 = PASCAL_STRING_CONSTANT("Hello world!");

让它表现相同,因为 \x0c\0\0\0Hello world! 存储在 rodata 中,c2 使用指向它的指针进行初始化。

我试过用

#define PASCAL_STRING_CONSTANT(c_string_constant) \
&((const PascalString) { \
.Length=sizeof(c_string_constant)-1, \
.Data=(c_string_constant), \
})

these 中的建议questions , 但它不起作用,因为 Data 是一个灵活的数组:我收到错误 error: non-static initialization of a flexible array member (使用 gcc,clang 给出了一个类似的错误)。

这在 C 中可能吗?如果是这样,PASCAL_STRING_CONSTANT 宏会是什么样子?

澄清

对于 C 字符串,以下代码块永远不会将字符串存储在堆栈中:

#include <inttypes.h>
#include <stdio.h>

int main(void) {
const char *c = "Hello world!";

printf("test %s", c);

return 0;
}

我们可以通过查看 the assembly 看到,第 5 行编译为仅将指针加载到寄存器中。

我希望能够使用 pascal 字符串获得相同的行为,并且使用 GNU 扩展是可能的。以下代码也从不将 pascal 字符串存储在堆栈中:

#include <inttypes.h>
#include <stdio.h>

typedef struct {
size_t Length;
char Data[];
} PascalString;

#define PASCAL_STRING_CONSTANT(c_string_constant) ({\
static const PascalString _tmpstr = { \
.Length=sizeof(c_string_constant)-1, \
.Data=c_string_constant, \
}; \
&_tmpstr; \
})

int main(void) {
const PascalString *c2 = PASCAL_STRING_CONSTANT("Hello world!");

printf("test %.*s", c2->Length, c2->Data);

return 0;
}

查看its generated assembly ,第 18 行也只是加载一个指针。

但是,我发现在 ANSI C 中执行此操作的最佳代码会生成将整个字符串复制到堆栈上的代码:

#include <inttypes.h>
#include <stdio.h>

typedef struct {
size_t Length;
char Data[];
} PascalString;

#define PASCAL_STRING_CONSTANT(initial_value) \
(const PascalString *)&(const struct { \
uint32_t Length; \
char Data[sizeof(initial_value)]; \
}){ \
.Length = sizeof(initial_value)-1, \
.Data = initial_value, \
}

int main(void) {
const PascalString *c2 = PASCAL_STRING_CONSTANT("Hello world!");

printf("test %.*s", c2->Length, c2->Data);

return 0;
}

generated assembly for this code ,第 19 行将整个结构复制到堆栈上,然后生成指向它的指针。

我正在寻找生成与我的第二个示例相同的程序集的 ANSI C 代码,或者寻找 ANSI C 无法实现的原因的解释。

最佳答案

您可以使用这个宏,它在其内容上命名变量的名称:

#define PASCAL_STRING(name, str) \
struct { \
unsigned char len; \
char content[sizeof(str) - 1]; \
} name = { sizeof(str) - 1, str }

创建这样一个字符串。像这样使用它:

const PASCAL_STRING(c2, "Hello world!");

关于c - 如何在 rodata 中初始化灵活数组并创建指向它的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58108327/

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