首页 > 解决方案 > 长到 size_t 的类型转换安全吗?

问题描述

我想用来ftell获取流的当前位置,但我希望能够将其类型转换为 a size_t,而这将是一个无符号的。有符号和无符号是不同的,因为一个是有符号的,另一个是无符号的。

的返回类型ftelllong,这与 不同size_t

那么,在这种情况下使用时,使用它而不是ftell安全吗?size_tlong

char *s = malloc(ftell(whateverstream));

我将ftell用于动态内存分配,所以我想知道使用 long 而不是 size_t 是否安全。

标签: cfilecastingio

解决方案


取决于“安全”的含义——将 long 转换为 size_t 始终是明确定义的,但这可能无法满足您的要求。

基本问题是 long 和 size_t 之间没有强制关系—— size_t 可能小于 long、更大或相同的大小。这取决于实现(机器和编译器)。

如果您使用的是 POSIX 系统,还有ftello,它返回 anoff_t而不是 long(它可能大于 long,并且大于或小于 size_t)。

所以为了完全安全,你需要检查所有可能的组合——检查 ftell(o) 的返回值是否不是负数,然后在将其转换为 size_t 后,检查它是否由于溢出而没有换行

long off = ftell(whatever);
size_t size = (size_t)off;
if (off < 0) {
    /* there was an error determining the size of the stream */
} else if (size != off) {
    /* overflow converting to size -- stream is too big */
} else {
    /* converted successfully */
}

推荐阅读