我使用的是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; //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;
}

godbolt live example

根据N2596/6.5.3.4 The 100 and 101 operators:

两个运算符的结果的值都是实现定义的, 并且它的类型(无符号整数类型)是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;

正在生成错误,因为系统上的szunsigned个64位值(long unsigned int),而off_1signed个64位值(long int). 在一般情况下,值sz不适用于off_1.

然而,在这一行中:

off_t off_2 = sizeof(long);

sizeof(long)compile time constant(在您的系统上是8),编译器可以验证它是否可以安全地赋给off_t off_2.

C++相关问答推荐

如何用C(使用两个s补数算术的32位程序)计算

如何通过Zephyr(Devicetree)在PR Pico上设置UTE 1?

getchar读css + z还是返回css?

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

我无法让LLDB正确运行我的可执行文件

C中的指针增量和减量(*--*++p)

正确的TCP/IP数据包 struct

如何在不使用其他数组或字符串的情况下交换字符串中的两个单词?

一旦运行长度超过2,编译器是否会优化";strnlen(mystring,32)>;2";以停止循环?

S在本文中的价值观到底出了什么问题?

这个空指针类型的转换是有效代码还是恶意代码?

Zlib:解压缩大文件导致";无效代码长度设置";错误

如何在不使用字符串的情况下在c中编写函数atof().h>;

C中的回文数字

C23标准是否向后兼容?

分配给静态变量和动态变量的位置之间有区别吗?

Ubuntu编译:C中的文件格式无法识别错误

将数组返回到链表

C 中 struct 体自赋值是否安全?特别是如果一侧是指向 struct 的指针?

int 与 size_t 与 long