我正在使用以下版本的 gcc:
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Run Code Online (Sandbox Code Playgroud)
考虑使用以下编译的简单代码片段-Werror=sign-conversion:
#include <stddef.h>
#include <sys/types.h>
int main(void){
size_t sz = sizeof(long);
off_t off_1 = sz; //error: conversion to 'off_t' {aka 'long int'} from 'size_t' {aka 'long unsigned int'} may change the sign of the result
off_t off_2 = sizeof(long); //compiles fine
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据N2596/6.5.3.4sizeof和_Alignof运算符:
两个运算符的结果值都是实现定义的,其类型(无符号整数类型)是
size_t,在(和其他标头)中定义<stddef.h>。
所以在我看来,结果off_t off_1 = sz;应该与 off_t 相同off_2 = sizeof(long);
为什么会off_t off_1 = sz;产生这个错误?
这行:
off_t off_1 = sz;
Run Code Online (Sandbox Code Playgroud)
产生错误是因为sz您的系统上有一个无符号64 位值 ( long unsigned int),并且off_1是一个有符号64 位值 ( long int)。在一般情况下,有些值sz无法拟合到 中off_1。
然而在这一行中:
off_t off_2 = sizeof(long);
Run Code Online (Sandbox Code Playgroud)
sizeof(long)是一个编译时常量(8在您的系统上),编译器可以验证它是否可以安全地分配到off_t off_2.