我试图以特定方式对齐字符串文字,因为我在代码中使用它的方式非常具体。我不想将它分配给变量,例如我的许多函数都将它用作直接参数。我希望它能够在本地范围或全球范围内工作。
用法示例:
char *str = ALIGNED_STRING("blah"); //what I want
foo(ALIGNED_STRING("blah")); //what I want
_Alignas(16) char str[] = "blah"; //not what I want (but would correctly align the string)
理想的解决方案是(_Alignas(16) char[]){ "blah" }
或使用GCC / Clang编译器扩展进行对齐(__attribute__((alignment(16))) char[]){ "blah" }
的更糟糕的情况,但都不起作用(它们被忽略,类型的默认对齐方式是使用)。
所以我的下一个想法是自己对齐,然后我使用字符串的函数可以正确地修复它。例如#define ALIGNED_STRING(str) (char*)(((uintptr_t)(char[]){ "xxxxxxxxxxxxxxx" str } + 16 - 1) & ~(16 - 1))
(其中包含' x'的字符串将代表了解真正字符串可以找到的位置所需的数据,这很容易,但仅为示例假设' x& #39;很好)。现在它在本地范围内工作正常,但在全局范围内失败。由于编译器抱怨它不是编译时常量(错误:初始化元素不是编译时常量);我会认为它会起作用,但似乎只有加法和减法才能在编译时对指针进行有效的操作。
所以我想知道是否还有什么可以实现我想做的事情?目前我只使用后一个例子(填充和手动对齐)并避免在全局范围内使用它(但我真的很想)。最好的解决方案是避免需要进行运行时调整(比如使用对齐限定符),但这似乎不可能,除非我将它应用于变量(但提到的并不是我想要的)做)。
答案 0 :(得分:1)
能够通过复合文字接近OP的需要。 (C99)
#include <stdio.h>
#include <stddef.h>
void bar(const char *s) {
printf("%p %s\n", (void*)s, s);
}
// v-- compound literal --------------------------v
#define ALIGNED_STRING(S) (struct { _Alignas(16) char s[sizeof S]; }){ S }.s
int main() {
char s[] = "12";
bar(s);
char t[] = "34";
bar(t);
bar(ALIGNED_STRING("asdfas"));
char *u = ALIGNED_STRING("agsdas");
bar(u);
}
输出
0x28cc2d 12
0x28cc2a 34
0x28cc30 asdfas // 16 Aligned
0x28cc20 agsdas // 16 Aligned