简体   繁体   English

写入有符号整数,就好像它在C ++中是无符号的一样

[英]Writing to a signed integer as if it is unsigned in C++

Is reinterpret_cast safe for this, and is it the best way to do this? reinterpret_cast是否安全,这是最好的方法吗?

For example, in the code below, I have a class called ibytestream , which allows the reading of uint16_t s and int16_t s from it. 例如,在下面的代码中,我有一个名为ibytestream的类,它允许ibytestream读取uint16_t s和int16_t s。 ibytestream::next is a vector<unsigned char>::iterator . 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);
}

I don't want to duplicate the code for converting the bytes to an integer, so I used reinterpret_cast for the signed version to reuse the code from the unsigned version. 我不想复制用于将字节转换为整数的代码,因此我使用reinterpret_cast作为签名版本来重用未签名版本的代码。 It works fine on my machine, but will it work in general on other modern machines? 它在我的机器上工作正常,但它会在其他现代机器上运行吗?

Yes, this is safe. 是的,这是安全的。

Three parts of the standard apply to make this determination: 该标准的三个部分适用于做出此决定:

  1. Alignment requirements of signed and unsigned types are the same 有符号和无符号类型的对齐要求是相同的
  2. Pointer casts between pointers to types with identical alignment requirements are allowed 允许在指向具有相同对齐要求的类型的指针之间进行转换
  3. When casts between glvalues are performed, the cast is valid if the cast between the corresponding pointers is valid. 当执行glvalues之间的强制转换时,如果相应指针之间的强制转换有效,则强制转换有效。

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. 对于每个标准有符号整数类型,存在相应的(但不同的)标准无符号整数类型: unsigned charunsigned short intunsigned intunsigned long intunsigned long long int ,每个都占用相同的量存储并具有相同的对齐要求。

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. 将“指向T1的指针”类型的prvalue转换为“指向T2的指针”类型(其中T1和T2是对象类型,T2的对齐要求不比T1更严格)并返回其原始类型会产生原始类型指针值。

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. 如果可以使用reinterpret_cast将“指向T1的指针”类型的表达式显式转换为“指向T2的指针”类型,则可以将类型T1的glvalue表达式强制转换为“对T2的引用”。 The result refers to the same object as the source glvalue, but with the specified type. 结果引用与源glvalue相同的对象,但具有指定的类型。

Yes, that should be perfectly fine. 是的,这应该是完全没问题的。 (Moving between ints and byte arrays have potential endian-ness issues, but that's another matter that applies to both signed and unsigned numbers.) (在int和字节数组之间移动有潜在的endian-ness问题,但这是另一个适用于有符号和无符号数字的问题。)

Something completely different: This bit: 完全不同的东西:这一点:

data = 0;
data |= *stream.next++;

...can be simplified: ......可以简化:

data = *stream.next++;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM