我有一个未知的typedef'd数字类型。如果可能的话,我想把它转换为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
)。
那我怎么能这样做呢?
答案 0 :(得分:1)
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 有符号整数和无符号整数比较中。当无符号整数适合有符号整数类型的范围时,它不会出现,因为将无符号整数类型转换为更宽的有符号整数类型没有问题。
答案 1 :(得分:0)
通过在测试中拉出正面
来担心缺少未签名版本if (val >= 0 )
{
if (val <= SIZE_MAX)
{
return (size_t) val;
}
}
// Handle error
return 0;
答案 2 :(得分:0)
检查否定案例后,检查相关类型的大小是否大于size_t
。如果是,请将SIZE_MAX
投射到some_int_type
类型并进行比较。如果不是,则该值不能大于SIZE_MAX
。
if (val < 0) {
// handle error
} else if ((sizeof(some_int_type) > sizeof(size_t)) && (val > (some_int_type)SIZE_MAX)) {
// handle error
} else {
return (size_t) val;
}