c ++ double cast void指针

时间:2018-02-12 00:59:22

标签: c++ casting

所以我偶然发现了这段关于arduino内存的代码

void EEPROM_writeDouble(int address, double value)
{
   byte* p = (byte*)(void*)&value;
   for (int i = 0; i < sizeof(value); i++)
   {
      EEPROM.write(address++, *p++);
   }
}

令我感兴趣的是这行代码byte* p = (byte*)(void*)&value;做得很完整,但没有弄清楚或者可能。所以我们有一个byte(char)类型的指针,它接受类型void*的值的引用并将其转换为字节指针?

3 个答案:

答案 0 :(得分:3)

此演员表没有实际原因。代码正在进行类型惩罚,编写代码的程序员可能会感到困惑。尝试从变量中获取单个字节时,可以使用unsigned char*指针。我假设的是这个例子中的byte。您无需为此指定void*指针。

答案 1 :(得分:3)

由于从double*byte*的转换不是有效static_castconst_cast,因此C ++会将请求转换的C样式转换解释为等同于{ {1}}。 (我假设reinterpret_castbyteunsigned char的typedef。)

在最初的C ++ 98标准和C ++ 03标准中,基本上没有保证char会做什么,只是说结果是&#34;实现定义&# 34 ;.因此,单个演员可能会获得指向reinterpret_cast变量存储开头的指针,但从技术上讲,你不能指望它。

另一方面,示例中的两次转化,从doubledouble*,然后从void*void*,都是有效的byte*次转化,所以C风格的演员都会有static_cast的行为。来自(非空)[cv] static_cast的{​​{1}}始终保证对象存储开头的static_cast点,从而产生指针假想void*重叠void*对象的存储空间。 (并且从bytedouble中读取属于不同类型对象的存储,这是严格别名规则的特定例外,所以没关系。)

请注意,从C ++ 11标准开始,unsigned char的行为以及C风格的强制转换更为某些类型的指针转​​换指定:([expr.reinterpret.cast] / 7 )

  

可以将对象指针显式转换为不同类型的对象指针。当{&#34}类型的char指向reinterpret_cast&#34;转换为&#34;指向 cv v&#34;的结果,结果为T1 cv T2 cv static_cast<如果T2*>(static_cast<void*>(v))都是标准布局类型,T1的对齐要求不比{{1}更严格或者,如果任一类型为void。将&#34;指针的prvalue转换为T2&#34;指向T2&#34;的类型&#34;指针(其中T1T1是对象类型,并且T2的对齐要求不比T1更严格,并且返回其原始类型会产生原始指针值。任何其他此类指针转换的结果都未指定。

因此,使用最近的标准模式,不再需要两个演员表。 (代码可能是先前编写的,或者可能仍然需要在多个C ++版本下工作,或者可能只是使用旧习惯编写。虽然使用C ++风格的转换来说明你真正意味着什么样的转换逻辑几乎总是比使用C风格的演员更好的主意。)

答案 2 :(得分:2)

如果(byte *)p是指针,则标准定义(byte *)(void *)pp相同。

更详细地说,N4659 [expr.reinterpret.cast] / 7将reinterpret_cast<T1 *>(p)定义为static_cast<T1 *>(static_cast<void *>(p)),[expr.cast]涵盖两个C风格的强制转换解析为static_cast在这种情况下。

所以这个演员是多余的,我们可以推测作者并不是很了解这门语言。