You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何将size_t变量赋值给off_t会触发符号转换错误?

为什么off_t off_1 = sz;触发符号转换错误而off_t off_2 = sizeof(long);不会?

环境信息

我使用的GCC版本如下:

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

问题代码

考虑以下使用-Werror=sign-conversion编译的简单代码片段:

#include <stddef.h>
#include <sys/types.h>

int main(void){
    size_t sz = sizeof(long);
    off_t off_1 = sz; // 错误:从'size_t'(别名'long unsigned int')转换为'off_t'(别名'long int')可能改变结果符号
    off_t off_2 = sizeof(long); // 编译正常
    return 0;
}

标准依据

根据N2596/6.5.3.4 sizeof和_Alignof运算符:

两个运算符的结果值由实现定义,其类型(无符号整数类型)为size_t,定义于<stddef.h>(及其他头文件)。

问题分析

核心原因是GCC对编译期常量表达式和变量的转换检查逻辑不同:

  • 对于sizeof(long):它是编译期可确定的常量表达式,GCC能直接计算出具体数值(在你的系统中,这个值远小于off_t(long int)的正数最大值)。编译器可以明确判断该值转换为有符号类型不会出现符号变化,因此不会触发-Wsign-conversion警告(也就不会因为-Werror升级为错误)。
  • 对于变量sz:尽管它被初始化为sizeof(long),但默认优化级别下,GCC不会将其视为常量。此时编译器只能基于类型进行检查:size_t是无符号类型,off_t是有符号类型,理论上存在无符号值超出有符号类型取值范围的可能(比如size_t的最大值转换为long int会变成负数),因此编译器会触发符号转换错误。

简单来说,编译器对常量可以做精准的数值范围校验,对变量只能做类型层面的安全预判。

内容的提问来源于stack exchange,提问作者Some Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:05:15