我有一个未知的 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/