【发布时间】:2019-10-19 14:58:01
【问题描述】:
假设您在 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 个字节使用对齐读取进入寄存器。
【问题讨论】:
-
您可以使用具有 8 字节对齐要求的联合类型。但首先问问自己:为什么你首先需要这个?这很可能是个坏主意。
-
我向你保证,这对我来说是一个非常好的主意。
-
这是一个指针数组,而不是字符串数组。请澄清你的意思是哪一个。 (如果你的意思是指针数组,你希望指针地址对齐,还是字符串文字地址对齐?)
-
使用 Clang 我发现 @aaaaaa123456789 的答案不会产生字符串对齐的汇编语言。
-
uint64_t value = *(uint64_t*) strings[i];在 C 中仍然是未定义的行为,因为它违反了严格的别名。你想要memcpy(value, strings[i], sizeof(value));,它将在支持未对齐负载的平台上内联。如果您可以将对齐信息传达给编译器(例如,通过具有指向 aligned 字符串或联合的指针数组),那么即使在 MIPS64 或任何不允许正常加载的平台上,它也应该内联不对齐。