Cs 默认 int 类型和 <stdint.h> 的 intXX_t 类型之间的转换如何工作?

How does casting between Cs default int type and <stdint.h>'s intXX_t types work?

我正在使用 C 中使用常规旧 int 类型的代码框架,其中有很多预先存在的代码。但是,我需要编写的代码要求我使用固定长度 int32_t。但是,我需要能够根据 int 从常规代码中获取输入,并输出到也只是常规 int 的变量。从 int32_tint 的转换是否保留变量的值,或者它的特定数据表示(在这种情况下,我可能需要移位以保留值)。相反,从 intint32_t 的转换会带来任何并发症吗?任何答案将不胜感激,尤其是任何一般和具体解释 stdint 库的转换约定的答案。

How does casting between Cs default int type and <stdint.h>'s intXX_t types work?

intXX_tint 大小、范围和有效类型相同时,实际上没有“工作”发生。

intXX_t 的范围比 int 宽时,所有值都保留在新类型中。高位是符号扩展。

intXX_t 的范围比 int 窄时,超出范围的值将以 实现定义的 方式进行转换。这是非常常见 mod 类似环绕(低位相同)

intXX_tint的范围相同时,类型可能不同,但通常是相同的。在 select 代码中(与 _Generic 一样),区别很重要。


int 有各种尺寸和编码。

  • 32 位(2 的补码):这很常见,尤其是在台式计算机上。

  • 16 位(2 的补码):这在小型嵌入式处理器中很常见。

  • 其他:包括非 2 的补码,一些 64 位图形处理器上的 64 位,一些旧机器或深奥机器上的非 2 的幂。对于 OP 的担忧,只需知道其他机器的存在,但 OP 非常 不太可能需要将代码移植到此类机器或从此类机器移植代码。


Does casting from int32_t to int preserve the value of the variable, or the specific data representation of it (in which case I may need to bitshift in order to preserve the value).

不需要移位。

  • 32 位(2 的补码):将 int32_t 转换为 int 不会丢失任何值信息。在 select 情况下,可能会发生 type 变化。 int32_t 可能已定义为 long,但 int32_t, int 更可能是完全相同的类型。

  • 16 位(2 的补码):将 int32_t 转换为 int 会丢失信息,因为范围要小得多。在这样的机器上,最好将 int32_t 转换为 long.


Conversely, does casting from int to int32_t introduce any complications?

  • 32 位(2 的补码):不太可能出现任何问题。

  • 16 位(2 的补码):某些情况值得审查,因为 int32_t 更宽,占用更多 space。


写得好的代码不太可能导致问题,但很多代码没有考虑可移植性。

对于 OP 的情况,我建议创建宏,而不是直接转换。由于新的工作要求,这将有助于跟踪对代码库的更改。此外,可以很容易地使用替代方案来调试范围 reduction/increase 问题。

// Use names per your coding style
#define inttoint32(i) ((int32_t) (i))
#define int32toint(i32) ((int) (i32))