【问题标题】:Round-trip pointer casting alignment往返指针投射对齐
【发布时间】:2014-02-26 20:54:21
【问题描述】:

如果我有一个指针 (unsigned long *uptr) 指向 (unsigned long) 的数组 - 或任何具有(通常)比 (char) 更严格对齐要求的类型 - 并强制转换:

char *bptr = (char *) uptr; /* always works. */

将(bptr) 转换为(unsigned long *) 是否会产生原始指针?我意识到将转换为具有更严格对齐要求的指针可能不会产生可以安全解除引用的指针,一般来说。但是标准是否保证这种情况下指针值的往返呢?

我无法想象(char *) 的实现不能按预期工作,因为它必须在其表示中至少有尽可能多的位来寻址字节。其他答案使 general 情况清楚。我从来没有想过这是否得到保证。

【问题讨论】:

  • 转换为 char* 并返回原始类型始终有效。
  • 如果您的原始指针指向unsigned long 或分配的内存大小等于或大于unsigned long。然后标准保证对齐。但它违反了严格的别名。
  • @Nick char 允许为任何类型设置别名。
  • @self 到 char,但不是从 char 到不兼容的类型。
  • 在 C++11 中你会因为 C++11 5.2.10/7 没问题。

标签: c pointers casting language-lawyer


【解决方案1】:

看起来你很好。 C11 6.3.2.3/7 说:

指向对象类型的指针可以转换为指向不同对象类型的指针。如果 结果指针未针对引用的类型正确对齐,行为是 不明确的。否则,当再次转换回来时,结果将等于 原始指针。当指向对象的指针转换为指向字符类型的指针时, 结果指向对象的最低寻址字节。的连续递增 结果,直到对象的大小,产生指向对象剩余字节的指针。

【讨论】:

    【解决方案2】:

    是的。

    引用与 Kerrek 相同的文本块,因为 char* 指针必须是 correctly aligned for the referenced type 未定义的行为被避免,result shall compare equal。

    如果它是除 char 以外的任何类型,或者如果您更改了 char* 指针的值,那么指针可能不再是 correctly aligned 并且您将返回 UB。

    你走的很窄,但去那里是绝对安全的。

    【讨论】:

    • 确实很窄!它实际上来自一些(现已修订的)代码,我懒得抓住两个指针。 不是捷径!
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多