c-如何将字符串文字与4的倍数地址对齐



我想确保给定的字符串文字最终位于2的倍数,甚至更好的是4的地址。

有没有任何方法可以实现这一点,最好不使用任何编译器特定的扩展?还是不可能?

我想这样做,使字符串地址的最低位为0,并且可以(ab)用作标记位。

您可以使用C11(但不能使用C99)来完成此操作。对于静态分配的缓冲区,您可以使用alignas来执行以下操作:

#include <stdio.h>
#include <stdalign.h>
alignas(4) char str[] = "this is aligned to at least 4 bytes";
int main() {
  char a;
  alignas(4) char str2[] = "and again";
  printf("%pn", &a);
  printf("%pn", str);
  printf("%pn", str2);
}

上面的技巧是,字符串文字实际上是用来初始化相同大小的char数组的,这使您可以在类型中使用alignas

对于动态分配的,可以使用aligned_alloc(size_t alignment, size_t size)而不是malloc

还有其他较老的非标准方法可以实现这一点,这些方法与GCC/Clang/Intel编译器一起使用,也可以追溯到很久以前,所以如果你没有C11,你可以用一些额外的预处理器工作来装扮它,例如:

#if __STDC_VERSION__ >= 201112L
# include <stdalign.h>
# define force_align(x) alignas(x)
#elif defined __GNUC__
# define force_align(x) __attribute__((aligned(x)))
#elif defined __MSC_VER
# define force_align(x) __declspec(align(x))
#else
# error Who are you?
#endif
force_align(128) int x; // Note: maybe your linker doesn't actually support 128 anyway!

这有利于C11解决方案,但使用GCC特定的扩展或MSVC扩展,而不存在其他合适的扩展。

在C99中,您可以使用并集来完成此操作,例如

#define ALIGNED_STR_UNION(N, S) const union { char s[sizeof S]; int align; } N = { S }
ALIGNED_STR_UNION(sssu, "XYZABC");

根据需要调整类型int

因此,sssu.s指的是字符。

.s可以像一样避免

#define ALIGNED_STR(S) ((const union { char s[sizeof S]; int align; }){ S }.s)
const char *sss = ALIGNED_STR("XYZABC");

然而,这个版本浪费了指针上的空间(包括位置无关代码的相对重定位),并且不允许在函数中声明静态文字。

使用非标准对齐属性可能比使用此属性更好。

最新更新