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

时间:2016-07-05 16:29:55

标签: c casting

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

那我怎么能这样做呢?

3 个答案:

答案 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;
}
相关问题