C 对齐特定用例的字符串文字

标签 c string gcc alignment clang

我正在尝试以特定方式对齐字符串文字,因为我在代码中使用它的方式非常具体。我不想将它分配给一个变量,例如我的许多函数都将它用作直接参数。我希望它在本地范围或全局范围内都能正常工作。

使用示例:

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' 是好的)。现在这在本地范围内工作正常,但在全局范围内失败。由于编译器提示它不是编译时常量(错误:初始化元素不是编译时常量);我原以为它会起作用,但似乎只有加法和减法是编译时指针上的有效操作。

所以我想知道是否有办法实现我想做的事情?目前我只是使用后一个示例(填充和手动对齐)并避免在全局范围内使用它(但我真的很想这样做)。最好的解决方案是避免需要进行运行时调整(比如使用对齐限定符),但这似乎是不可能的,除非我将它应用于变量(但如前所述,这不是我想要做的)。

最佳答案

能够通过复合文字接近 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

关于C 对齐特定用例的字符串文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34796571/

相关文章:

c - 如果我们同时使用两个传感器,为什么它会向我们的电脑发送错误数据?

java - 从字符串中提取目录

java - 转义字符串中的特殊 XML 字符

c++ - gcc -I 和 -L 选项似乎不起作用

windows - 如何使用依赖于 libiconv 的 MinGW 安装 go 包

c - 如何解决此 MS 运行时 DLL 加载程序运行时错误 (R6034)

c - 如何在 int* 类型上使用 strcpy 和 memcpy

c++ - Eclipse CDT 控制台输出未显示在带有路径的调试中,也未显示在没有路径的运行中

c - struct task_struct 成员?

c++ - 解析字符串并将标记作为参数传递