将 typedef 数字类型转换为 size_t 捕获溢出

标签 c casting

我有一个未知的 typedef 数字类型。如果可能的话,我想将其转换为 size_t (阅读:如果它适合 size_t 的范围),否则会陷入某些错误处理代码。

是否有一种可移植的方式来做到这一点?

实际上我想做的是:

some_int_type val = <blah>;
if (val < 0 || val > SIZE_MAX) {
    // handle error
} else {
    return (size_t) val;
}

但是,这不起作用,因为 val 可能已签名。

我的第二个想法是这样做:

if (val < 0 || (unsigned_some_int_type) val > SIZE_MAX) {
    // handle error
} else {
    return (size_t) val;
}

这会起作用(我认为) - 除了我没有 some_int_type 的未签名版本。我可以将它们都转换为 some_int_type,但如果 some_int_type 小于 size_t 则无法正常工作(并且如果some_int_type 也已签名,现在我想了一下)。我可以将它们都转换为 uintmax_t - 除了某些编译器实际上具有大于 uintmax_t 的整数类型。 (值得注意的是,__[u]int128)。

那么我该如何去做呢?

最佳答案

OP的原始代码应该没问题

some_int_type val = <blah>;
if (val < 0 || val > SIZE_MAX) {
    // handle error
} else {
    return (size_t) val;
}

OP commented to @Olaf “错误:有符号和无符号整数表达式之间的比较”。要么OP确实看到了警告,要么警告被视为错误。 IAC,这不是 C 的错误。

如果 OP 无法忽略警告/错误,则仅根据需要轻轻转换为 size_t。如果未知类型比 size_t 宽,则将其乘以 (size_t)1 不会更改类型,并且不会出现比较警告。 IAC,val的值不会改变。

#include <stdint.h>
if (val < 0 || (size_t)1 * val > SIZE_MAX) {

让编译器优化它。只有较小的编译器才能使用 (size_t)0 + val

<小时/>

此外:消息“有符号和无符号整数表达式之间的比较”仅在select有符号整数和无符号整数比较中出现。当无符号整数适合有符号整数类型的范围时,它不会出现,因为将无符号整数类型转换为更宽的有符号整数类型不会出现问题。

关于将 typedef 数字类型转换为 size_t 捕获溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38208384/

相关文章:

类和指针的 C++ 类型转换

c++ - C++数学计算中的内部时间变量

c++ - 将范围有限的 float 转换为保持排序顺序和精度的无符号整数?

c - void** 指针和 void*[] 作为函数参数

c - Makefile:将 C 代码转换为 mex 代码(链接错误)

C函数剖析(地址好像有偏移)

c - __FUNCT__ 有什么用?

c - 为什么这个函数会让一个数组改变另一个变量?

c - C 程序的奇怪行为::Kernighan & Ritchie 练习 2-3

c - 关于C malloc函数的问题