【问题标题】:How can I align a string literal to an address which is multiple of 4?如何将字符串文字与 4 的倍数的地址对齐?
【发布时间】:2016-04-10 12:06:45
【问题描述】:

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

有什么方法可以实现,最好不使用任何特定于编译器的扩展?还是不可能?

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

【问题讨论】:

  • 将字符串与地址对齐我们能理解什么...你能解释一下这是什么意思吗???
  • @Xoce:c 中的字符串是指向 char 的简单指针。任何指针都有地址。我想以某种方式确保所述地址是四的倍数。

标签: c string c99 string-literals


【解决方案1】:

您可以使用 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("%p\n", &a);
  printf("%p\n", str);
  printf("%p\n", str2);
}

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

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

还有其他较旧的非标准方法可以与 GCC/Clang/Intel 编译器一起使用,这些方法也可以追溯到很长一段时间,所以如果你没有 C11 可用,你可以用一些额外的 pre-处理器工作,例如:

#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 解决方案,但使用 a GCC specific extensionMSVC one 没有其他合适的存在。

【讨论】:

    【解决方案2】:

    在 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");
    

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

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

    【讨论】:

      猜你喜欢
      • 2023-03-25
      • 2011-01-05
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多