【问题标题】:Performing arithmetic on a void pointer in C++在 C++ 中对 void 指针执行算术运算
【发布时间】:2013-11-06 00:19:43
【问题描述】:

我正在尝试对地址执行算术运算。我需要确保它位于 4 字节字边界上。这需要我获取指针的无符号整数表示来执行一些数学运算。我已经这样做了:

//memStartAddr is of type void* (from an external API function)
data32 tempAddr = reinterpret_cast<data32>(memStartAddr);
//adjust pointer to the next word boundary if needed
tempAddr = wordAlign(tempAddr);
//memStartAddress is a class variable of type unsigned char*
memStartAddress = reinterpret_cast<data8*>(tempAddr);
//calculate bytes lost due to above adjustment
data32 delta = (tempAddr - reinterpret_cast<data32>(memStartAddress));
//Take advantage of integer arithmetic to ensure usable size is a multiple
//of 4 bytes. Remainders are lost. Shrinks usable size if necessary.
memSize = ((size - delta) / 4) * 4;

这一切都在我的测试中有效,但是,使用 reinterpret_cast 被认为是一种禁止的做法。还有另一种方法可以做到这一点吗?或者是这里有必要的规则例外?

【问题讨论】:

  • 我认为这是使用reinterpret_cast的有效案例
  • 谁说reinterpret_cast是被禁止的?您是否遵循某人的编码约定?
  • 如果reinterpret_cast是被禁止的,为什么ISO C++的人认为这是一个好主意并批准将其添加到语言中,为什么每个C++编译器都必须实现它才能符合?在被禁止的事情上浪费了很多生产力,不是吗!
  • 我同意,但是,这是我在我工作的团队中必须遵循的编码指南中的一条规则,这就是为什么我正在寻求一种可读、直观的解决方法。我相信它必须防止知识渊博的人错误地使用它,因为如果你不小心,你真的会把事情搞砸。
  • @radensb:“将指针对齐到 4 字节边界”会在需要 8 字节的平台上搞砸。 reinterpret_cast 的明确意图是这些危险的事情是可能且可见。在 C 中,等价于 *(type*)(&amp;expr),这很容易被忽略。

标签: c++ pointers casting


【解决方案1】:

您正在寻找memStartAddress = std::align(4, objSize, memStartAddr, objSize+3);。标准函数比你需要的要灵活一点,所以你需要告诉它你最多想要 +3 更改地址。

【讨论】:

    【解决方案2】:

    一个棘手的方法可能是让指针指向初始地址 然后在指针上执行 + 1 --> 这将根据它指向的变量类型的字节大小自动生成下一个地址。 注意:确保在指针上而不是在地址上执行 +1(int* initialAddress --> 在 initialAddress 上而不是在 *initialAddress 上执行操作)

    然后您可以在两者之间进行减法运算,您将得到字节数。

    【讨论】:

    • 我想到了这种方法。问题是我必须执行一些整数运算才能得到我正在寻找的数字。例如:return ((reinterpret_cast(memAddr) + 3) / 4) * 4. 这将返回 memAddr 的无符号版本或下一个 4 字节边界的地址
    【解决方案3】:

    我建议你避免分裂。
    试试这个:

    unsigned int pointer_value = (unsigned int) pointer;
    if ((pointer_value & 0x3U) == 0U)
    {
        // Pointer is on 4 byte boundary.
    }
    

    当优化级别设置为高时,某些编译器可能只优化除以 4 和乘以 4。我使用的嵌入式编译器将在除以 4 时调用除法函数,而不是右移,除非优化设置被调高。

    【讨论】:

    • 这很有趣。我知道旧的 C 风格转换不会符合我必须遵循的编码准则,但是消除整数除法是一个不错的选择!
    猜你喜欢
    • 2011-06-30
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2015-12-23
    • 2021-04-29
    • 2020-10-03
    相关资源
    最近更新 更多