【问题标题】:Approved syntax for raw pointer manipulation经批准的原始指针操作语法
【发布时间】:2011-01-18 02:56:12
【问题描述】:

我正在制作一个内存块复制例程,需要以有效的块处理原始内存块。我的问题不是关于我正在制作的专门复制例程,而是关于如何正确检查 C 中的原始指针对齐。

我有一个原始的内存指针,假设它已经被转换为非空字符 *。 在我的架构中,当它与 64 字节块对齐时,我可以非常有效地复制 64 字节块中的内存。所以(标准)技巧是我将在头部和/或尾部“手动”做一个简单的 0-63 字节副本,以将副本从任意长度的任意 char* 转换为具有多个倍数的 64 字节对齐指针长度为 64 字节。

现在的问题是,您如何合法地“检查”指针以确定(和操纵)其对齐方式? 显而易见的方法是将其转换为整数并仅检查位:

char *pointer=something.
int p=(int)pointer;
char *alignedPointer=(char *)((p+63)&~63);

注意这里我意识到alignedPointer 不指向与指针相同的内存......这是我可以调用我的高效复制例程的“四舍五入”指针,我将处理任何其他字节手动开始。

但是编译器(有理由)在将指针转换为整数时会发疯。但是我还能如何检查和操作 LEGAL C 中指针的低位?理想情况下,使用不同的编译器我不会收到错误或警告。

【问题讨论】:

  • 应该没问题,只要int 的大小与您的指针类型相同。
  • 啊,但是您假设指针以二进制形式存储从 MSB 到 LSB。我们有什么? 未定义的行为!(就像致命武器的人所说的外交豁免权!)仅仅因为它在现实世界中有效并不能使它变得更少未定义。 ;-)
  • @pennington - 你为什么说字节序是预设的?如果你说“& 0x0f”,0x0F 的含义是明确的。它将由编译器以与指针相同的字节序存储。不会吗?现在,如果您将指针转换为字节数组,那么您确实需要担心。
  • 您平台上的系统memcpy( ) 真的没有经过调整以利用这一点吗?

标签: c pointers alignment bit-manipulation portability


【解决方案1】:

对于大到足以容纳指针的整数类型,C99 stdint.h 有:

对于数据长度有:

早在 C99 之前就已经存在了。

如果您的平台没有这些,您可以通过仍然使用这些类型名称并为它们设置合适的typedefs 来最大限度地提高代码的可移植性。

【讨论】:

  • 啊,但是如何从未对齐的指针中获得 aligned 指针?
【解决方案2】:

我不认为过去人们不愿意做自己的 bit-banging,但也许当前的“不要碰那个”的情绪将有利于某人创建某种用于对齐指针的标准库.由于缺少某种官方 api,您别无选择,只能通过 AND 和 OR。

【讨论】:

  • +1 在过去,没有未定义的行为。如果你的编译器做了你想让它做的事情,那就足够了。
【解决方案3】:

尝试使用保证与指针大小相同的数据类型而不是 int(Win32/64 上的 INT_PTR)。也许编译器不会吓坏太多。 :) 或者使用联合,如果 64 位兼容性不重要。

【讨论】:

    【解决方案4】:

    从整数转换指针是有效的,但结果是实现定义的。见标准第 6.3.2.3 节。其意图似乎是任何熟悉该系统的人都会期望得到结果,实际上这似乎是实践中的例行公事。

    如果所讨论的架构可以有效地交替操作指针和整数,而问题只是它是否适用于该系统的所有编译器,那么答案是它可能无论如何都可以。

    (当然,如果我正在编写这段代码,我会认为它是原样的,直到证明不是这样。我的经验是,给定系统的编译器在这种级别上的行为都非常相似;汇编语言只是建议一种特定的方法,然后所有人都采用。)

    “可能有效”虽然不是很好的一般建议,所以我的建议是编写有效的代码,将其包围起来足够合适 #ifdefs 只有已知的编译器才能编译它,然后推迟在其他情况下发送至memcpy

    #ifdef 很少是理想的,但与其他可能性相比,它相当轻量级。如果需要实现定义的行为或特定于编译器的技巧,那么无论如何选择都是非常有限的。

    【讨论】:

    • “汇编语言只是提出了一种特定的方法”——我将开始在软件辩论中使用这个短语,不管适用性如何。
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 2013-04-25
    相关资源
    最近更新 更多