在基元类型指针之间进行强制转换
Casting between primitive type pointers
是否定义如下:
char* charPtr = new char[42];
int* intPtr = (int*)charPtr;
charPtr++;
intPtr = (int*) charPtr;
intPtr
未正确对齐(至少在两种情况中的一种情况下)。把它放在那里是违法的吗?UB在任何阶段都在使用它吗?你怎么能用,怎么不能用?
通常,如果int
的对齐要求大于char
的对齐要求,则结果是未指定的(5.2.10p7)。结果将是类型为int *
的有效值,因此可以用operator<<
将其打印为指针或转换为intptr_t
。
因为结果有一个未指定的值,除非实现指定,否则间接它并对生成的int
左值执行左值到右值转换是未定义的行为(未赋值的上下文除外)。转换回char *
不一定是往返的。
然而,如果原始char *
本身是从int *
转换的结果,那么转换到int *
算为往返行程的后半部分;在这种情况下,将定义强制转换。
特别地,在上述char *
是new[]
表达式的结果的情况下,我们保证(5.3.4p10)char *
指针对于int
和sizeof(int) <= 42
是适当对齐的。由于new[]
表达式是从分配函数获得其存储的,因此3.7.4.1p2适用;可以转换void *
指针指向具有基本对齐要求的任何完整对象类型的指针,然后用于访问对象[…],这强烈暗示,连同5.3.4p10的注释,new[]
表达式返回的char *
指针也是如此。在这种情况下,int *
是指向未初始化的int
对象的指针,因此对其间接执行左值到右值转换是未定义的(3.8p6),但对其间接的赋值是完全定义的。int
对象在分配的存储中(3.7.4.1p2),因此将int *
转换回char *
将产生每1.8p6的原始值。这对于递增的char *
指针不适用,因为除非sizeof(int) == 1
不是int
对象的地址。
当然,首先:指针保证在第一种情况(根据§5.3.4/10和§3.7.4.1/2),并且可能是正确的在两种情况下都对齐。(显然,如果sizeof(int) == 1
,但是即使不是这样,实现也不会必须具有对齐要求。)
为了清楚起见:你的演员阵容都是reinterpret_cast
。
除此之外,这是一个有趣的问题,因为就我看得出来,就有关标准。转换的结果是未指明(根据§5.2.10/7);你甚至不能保证将其转换回CCD_ 31将导致原始价值。(例如,在机器上显然不会其中CCD_ 32小于CCD_ 33。)
当然,在实践中:标准要求CCD_ 34的值对于任何值都充分对齐这可能适合它,所以你保证能够做到:
intPtr = new (charPtr) int;
这与你的演员阵容效果完全相同,因为int
的默认构造函数是no-op。(假设sizeof(int) <= 42
.)所以很难想象一个实现其中第一部分失效。您应该能够使用CCD_ 37就像任何其他合法获得的CCD_。和将其转换回char*
将以某种方式产生的想法与原始char*
的值不同荒谬的
在第二部分中,所有的赌注都被取消了:你绝对不能取消引用指针(除非您的实现保证否则),并且也很可能将其转换回到CCD_ 41会产生不同的结果。(想象一个词寻址机器,例如,其中将char*
转换为int*
四舍五入。然后转换回比原来高CCD_ 45的CCD_。或尝试转换未对齐的指针总是导致在空指针中。)
- 构造函数和转换运算符之间的重载解析
- C ++中无符号位长度类型之间的隐式转换,即uint8_t,uint16_t
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- Cxx.jl 在 Julia Complex 和 std::complex 之间进行转换
- 如何在 std::string 和 Aws::String 之间进行转换?
- 转换字符时Arduino DUE 和 Arduino UNO 之间的区别
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- 在 Rcpp 中的字符串类型之间转换时出错
- 如何声明不同类型的模板化类之间的转换
- C 和 C++ 中的函数指针转换之间的差异
- 与浮点转换之间的规范化整数
- 重新解释强制转换和 C 样式转换之间的 C++ 区别
- C++ get 和类型转换之间的用法有什么区别?我应该使用哪一个?
- printf函数参数之间的序列点;转换之间的顺序点是否重要
- Clang和GCC中不明确基类转换之间的行为差异
- 转换之间的双和字节数组,为传输ZigBee API
- 隐式转换和显式转换之间的区别
- interpret_cast和C样式强制转换之间的区别是什么