【问题标题】:Is typecasting long to size_t safe?长到 size_t 的类型转换安全吗?
【发布时间】:2020-11-01 18:29:37
【问题描述】:

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

ftell 的返回类型是long,与size_t 不同。

那么,在这种情况下使用ftell 时,使用size_t 代替long 是否安全?

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

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

【问题讨论】:

  • ftell 可以返回负值,因此该行代码安全。
  • 你应该总是先检查返回值,如果发生错误它会是负数。然后你知道它是积极的并且可以使用它
  • 通常是的,它是安全的(在验证返回为非负数之后),而size_tlong 通常应该具有相同的等级,实现可以选择做不同的事情@987654321 @
  • 你怎么知道size_t“这将是一个无符号长整数”?如果您知道因为它特定于您正在使用的 C 实现,那么将非负的 long 值转换为 size_t 是安全的。如果你“知道”它是因为你认为 C 是这样工作的,那么它就是不安全的。 C 标准允许size_tlong 窄,并且磁盘上的文件可以大于内存地址空间。
  • @EricPostpischil 你是对的。而不是说unsigned long,我应该知道它是unsigned而不是signed。感谢您的认可。

标签: c file casting io


【解决方案1】:

取决于您所说的“安全”——将 long 转换为 size_t 始终是明确定义的,但这可能不是您想要的。

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

如果您使用的是 POSIX 系统,还有 ftello,它返回 off_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 */
}

【讨论】:

  • 如果溢出,程序会不会有什么不好的事情发生?
  • size_t 是无符号类型,因此溢出是明确定义的——该值以类型大小为模。
猜你喜欢
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
相关资源
最近更新 更多