C 如何在静态数组中对每个字符串进行8字节对齐?

C 如何在静态数组中对每个字符串进行8字节对齐?,c,gcc,assembly,clang,C,Gcc,Assembly,Clang,假设在一个C程序(不是C++)中有一个文本字符串的静态数组,其长度可以变化很大。您所关心的是每一个都从8字节的边界开始。有没有办法确保GCC或CLANG会这样对齐每个字符串? 您还希望节省空间,因此填充字符串使其大小相同不是一个选项 static char* const strings[] = { "a", "longer string", "bcd", "wow a really long string", "foo", ... }; 这里的目标是这样做: uint64_t valu

假设在一个C程序(不是C++)中有一个文本字符串的静态数组,其长度可以变化很大。您所关心的是每一个都从8字节的边界开始。有没有办法确保GCC或CLANG会这样对齐每个字符串? 您还希望节省空间,因此填充字符串使其大小相同不是一个选项

static char* const strings[] = {
    "a", "longer string", "bcd", "wow a really long string", "foo", ...
};
这里的目标是这样做:

uint64_t value = *(uint64_t*) strings[i];

这样,读取不会跨越生成的asm代码中的两个四字,即字符串的前8个字节使用对齐读取进入寄存器。

假设您的意思是希望字符串文本对齐;这是不可能的。但是,通过使用自定义对齐方式制作阵列,可以获得类似的效果,例如:

_Alignas(8) static char const s1[] = {"a"};
_Alignas(8) static char const s2[] = {"longer string"};
_Alignas(8) static char const s3[] = {"bcd"};
_Alignas(8) static char const s4[] = {"wow a really long string"};
_Alignas(8) static char const s5[] = {"foo"};

char const *const strings[] = { s1, s2, s3, s4, s5 };
您可以通过对每个条目使用预处理器宏来保存键入

另见


根据C17标准,您还可以使用带有对齐说明符的复合文字:

char const *const strings[] = 
{
    (_Alignas(8) char const[]){"a"},
    (_Alignas(8) char const[]){"longer string"},
};

尽管有些编译器还不支持此功能。

您可以使用具有8字节对齐要求的联合类型。但是首先问问你自己:为什么你首先需要这个?这很可能是个坏主意。我向你保证,在我的情况下,这是一个非常好的主意。这是一个指针数组,而不是字符串数组。请澄清你的意思。(如果你指的是一个指针数组,你希望指针地址对齐,还是字符串文字地址对齐?)在C中仍然是未定义的行为,因为它违反了严格的别名。您需要
memcpy(value,strings[i],sizeof(value))将在支持未对齐负载的平台上进行内联。如果您可以将对齐信息传递给编译器(例如,通过使用指向对齐字符串或联合的指针数组),那么即使在MIPS64或任何不允许正常加载未对齐的平台上,它也应该内联。为了避免创建所有这些外部变量,你也可以使变量
sX
成为静态变量
static
,或者只使用复合文本。它生成例如:.p2align 3_s1:.asciz“a”@JensGustedt复合文字根据标准不允许使用对齐说明符。同意
static
@M.M这是规范中的一个错误,已在C17中更正。现在它说:对齐说明符只能出现在声明的声明说明符中,或者出现在成员声明的说明符限定符列表中,或者出现在复合文字的类型名称中。@denk,我不明白什么是不好的,这里,这是C17的一个改进,不是吗?对于C语言的未来来说,仅仅提出建议是没有帮助的。总得有人来做这项工作。因此,请加入您的国家标准机构,并参加WG14。我们需要所有的人手。