c++ - 这是类型转换还是某种指针算法?

标签 c++ pointers casting

我遇到了一行用 C++ 编写的代码:

long *lbuf = (long*)spiReadBuffer;

事实证明,“spiReadBuffer”是一个包含 12 个元素的字节数组。但我有点困惑。我想我对指针的定义很熟悉,我可以看到“lbuf”是一种“long”指针。我还认为对于类型转换我们可以做这样的事情:

y = (int) x;    

但是如果我像我的第一个例子一样在“int”后面加上一个“*”,在“long”后面有一个怎么办? 如果这是一个非常微不足道的问题,我深表歉意,但是当我浏览类型转换和指针主题时,我没有遇到我的案例,我也没有真正理解它。 如果您能指导我或向我介绍任何相关 Material 或资源,我将不胜感激。

最佳答案

这称为类型双关。它欺骗编译器读取对象占用的内存,就好像它是另一种类型一样。

在您的例子中,数组 spiReadBuffer 衰减为指向其第一个元素的指针,然后指针被转换并存储。当您取消引用此指针时,您将访问数组的开头,就好像它是一个 long

这种方法的问题在于它会触发未定义的行为(参见严格别名)。因此,即使它在很多情况下都能正常工作,它也可能会在没有通知的情况下中断。

有两种方法(据我所知)可以安全地输入双关语。第一个是符合标准的:std::memcpy

char spiReadBuffer[12];
long rbAsLong;
std::memcpy(&rbAsLong, &spiReadBuffer, sizeof rbAsLong);
// rbAsLong contains the first four bytes of spiReadBuffer, reinterpreted as a long.

第二个涉及编译器通常提供的扩展(但您应该检查),它扩展了 union 的行为。

union {
    char buf[12];
    long asLong;
} spiReadBuffer;

标准声明写入 union 成员然后从另一个成员读取是未定义的行为。这些编译器扩展选择将其定义为安全的重新解释。

关于c++ - 这是类型转换还是某种指针算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29966930/

相关文章:

string - 构建 16 位操作系统 - 字符数组不起作用

c++ - 重新分配指针给出错误

结构的 C 指针 - 段错误

C# 从接口(interface)转换类型

c# - 在共享相同接口(interface)的类之间进行转换

ios - 将 UnsafeMutablePointer 转换为 UnsafeMutableRawPointer

c++ - 如何从可从 C++ 代码调用的 Ada 源构建静态库?

c++ - 在 Mac OS 上测量 deltatime 毫秒数的最佳方法?

c++ - Capstone cs_disasm 仅反汇编一小部分代码

c++ - 在 C++ 项目之间共享中间文件?