写入有符号整数,就好像它在 C++ 中是无符号的一样
Writing to a signed integer as if it is unsigned in C++
reinterpret_cast
这样做安全吗?这是最好的方法吗?
例如,在下面的代码中,我有一个名为 ibytestream
的 class,它允许从中读取 uint16_t
s 和 int16_t
s。 ibytestream::next
是 vector<unsigned char>::iterator
.
inline ibytestream& operator>>(ibytestream& stream, uint16_t& data) {
data = 0;
data |= *stream.next++;
data <<= 8;
data |= *stream.next++;
return stream;
}
inline ibytestream& operator>>(ibytestream& stream, int16_t& data) {
return stream >> reinterpret_cast<uint16_t&>(data);
}
我不想重复将字节转换为整数的代码,因此我使用 reinterpret_cast
作为签名版本以重用未签名版本的代码。它在我的机器上运行良好,但它在其他现代机器上是否普遍运行?
是的,那应该没问题。 (在整数和字节数组之间移动有潜在的字节顺序问题,但这是适用于有符号和无符号数字的另一件事。)
完全不同的东西:这个位:
data = 0;
data |= *stream.next++;
...可以简化为:
data = *stream.next++;
是的,这是安全的。
标准的三个部分适用于做出此决定:
- 有符号和无符号类型的对齐要求相同
- 允许在指向具有相同对齐要求的类型的指针之间进行指针转换
- 执行左值之间的转换时,如果相应指针之间的转换有效,则转换有效。
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char
, unsigned short int
, unsigned int
, unsigned long int
,
and unsigned long long int
, each of which occupies the same amount of storage and has the same alignment requirements.
An object pointer can be explicitly converted to an object pointer of a different type. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.
A glvalue expression of type T1 can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. The result refers
to the same object as the source glvalue, but with the specified type.
reinterpret_cast
这样做安全吗?这是最好的方法吗?
例如,在下面的代码中,我有一个名为 ibytestream
的 class,它允许从中读取 uint16_t
s 和 int16_t
s。 ibytestream::next
是 vector<unsigned char>::iterator
.
inline ibytestream& operator>>(ibytestream& stream, uint16_t& data) {
data = 0;
data |= *stream.next++;
data <<= 8;
data |= *stream.next++;
return stream;
}
inline ibytestream& operator>>(ibytestream& stream, int16_t& data) {
return stream >> reinterpret_cast<uint16_t&>(data);
}
我不想重复将字节转换为整数的代码,因此我使用 reinterpret_cast
作为签名版本以重用未签名版本的代码。它在我的机器上运行良好,但它在其他现代机器上是否普遍运行?
是的,那应该没问题。 (在整数和字节数组之间移动有潜在的字节顺序问题,但这是适用于有符号和无符号数字的另一件事。)
完全不同的东西:这个位:
data = 0;
data |= *stream.next++;
...可以简化为:
data = *stream.next++;
是的,这是安全的。
标准的三个部分适用于做出此决定:
- 有符号和无符号类型的对齐要求相同
- 允许在指向具有相同对齐要求的类型的指针之间进行指针转换
- 执行左值之间的转换时,如果相应指针之间的转换有效,则转换有效。
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type:
unsigned char
,unsigned short int
,unsigned int
,unsigned long int
, andunsigned long long int
, each of which occupies the same amount of storage and has the same alignment requirements.An object pointer can be explicitly converted to an object pointer of a different type. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.
A glvalue expression of type T1 can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. The result refers to the same object as the source glvalue, but with the specified type.