如果使用显式cast,简短的回答是肯定的,但要详细解释它,有三个方面需要考虑:
1) Legality of the conversion
static_cast<unsigned char*>(static_cast<void *>(data_in))
这可以缩写为(§5.2.10/7)
reinterpret_cast<unsigned char *>(data_in)
因为char
是一种标准布局类型(§3.9.1/7,8和§3.9/9),且标志性不会改变对齐方式(§3.9.1/1).它也可以写成C风格的演员阵容:
(unsigned char *)(data_in)
同样,这是双向的,从unsigned*
到signed*
,再回到unsigned*
.此外,还可以保证,如果您将此过程单向应用,然后再反向应用,指针值(即指针指向的地址)不会发生更改(§5.2.10/7).
所有这些不仅适用于signed char *
和unsigned char *
之间的转换,还分别适用于char *
/unsigned char *
和char *
/signed char *
.(char
、signed char
和unsigned char
在形式上是三种截然不同的类型,§3.9.1/1.)
需要说明的是,使用三种强制转换方法中的哪一种并不重要,但必须使用其中一种.仅仅传递指针是行不通的,因为转换虽然合法,但不是标准转换,因此不会隐式执行(如果您try ,编译器将发出错误).
2) Well-definedness of the access to the values
如果程序试图通过除以下类型之一之外的glvalue种方式访问对象的存储值,则行为未定义:
- [...]
- 与对象的动态类型相对应的有符号或无符号类型,
- [...]
char
或unsigned char
型.
Therefore, accessing a signed char
(or char
) through an unsigned char*
(or char
) and vice versa is not disallowed by this rule – you should be able to do this without problems.
3) Resulting values
取消类型转换指针的引用后,是否可以使用所获得的值?重要的是要记住,上述指针的转换和取消引用相当于重新解释(而不是更改!)存储在字符地址的位模式.那么,当有符号字符的位模式被解释为无符号字符的位模式(反之亦然)时,会发生什么情况呢?
当从无符号变为有符号时,typical effect将是0到128之间的值,不会发生任何变化,128以上的值将变为负值.反过来类似:从有符号到无符号时,负值将显示为大于128的值.
但这一行为被"标准"定为isn't actually guaranteed.标准唯一保证的是,对于所有三种类型(char
、unsigned char
和signed char
),所有位(不一定是8位,btw)都用于值表示.因此,如果您将一个解释为另一个,复制几个副本,然后将其存储回原始位置,您可以确保不会丢失信息(按照您的要求),但是您不一定知道这些值的实际含义(至少不是以完全可移植的方式).