首页 > 解决方案 > 双重转换,从 uint16 到 int32 同时保持标志

问题描述

我有一个 uint16_t 变量,但存储在其中的数据是一个 int16_t 值。

我现在想在保留符号的同时将 uint16_t 变量转换为 int32_t。

(我知道它是用 c 标记的,但代码是 c++ 但这并不重要,因为我使用的是 c-typecasts)

#include <stdio.h>
#include <iostream>
#include <stdint.h>

using namespace std;


int main() {    
    uint16_t source = 32769; // is actually -32767

    cout << source                      << endl
         << (int16_t) source            << endl
         << (int32_t) source            << endl
         << (int32_t)(int16_t) source   << endl;
}

输出:

32769

-32767

32769

-32767

双重演员给了我正确的结果。

我只想知道双重转换是否是有效的标准 c 代码,每个编译器的行为方式都相同。或者一些编译器可以跳过第一次演员或其他什么?

标签: c++

解决方案


我只想知道双重转换是否是有效的标准c代码

只要从无符号整数转换为有符号整数的值可以在目标类型中表示,它就是有效的 C 和 C++ 代码。在这种情况下,它不能超出记录的值范围int16_t

每个编译器的行为方式都相同。或者一些编译器可以跳过第一次演员或其他什么?

这很复杂,因为您使用的是 C++,但询问的是 C。所以我会同时回答这两个问题。在 C++ 直到 C++20 和 C 中,这是实现定义的。这意味着编译器必须具有记录在案的行为,但是不能保证该行为是相同的。

如前所述,这在 c++20 中发生了变化,以承认几乎没有现代实现支持除了二进制补码整数之外的任何东西,此时结果被定义为“目标类型的唯一值等于源值模 2 n,其中 n 是用于表示目标类型的位数”来源


推荐阅读