I’m using gcc of the following version:
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Consider the following simple code fragment compiled with -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;
}
According to N2596/6.5.3.4 The sizeof
and _Alignof
operators:
The value of the result of both operators is implementation-defined,
and its type (an unsigned integer type) issize_t
, defined in
<stddef.h>
(and other headers).
So it appeared to me that the result of off_t off_1 = sz;
should be the same as off_t off_2 = sizeof(long);
Why does off_t off_1 = sz;
produces this error?
This line:
off_t off_1 = sz;
Is producing an error because sz
on your system is an unsigned 64 bit value (long unsigned int
), and off_1
is a signed 64 bit value (long int
).
In the general case there are values of sz
that cannot be fitted into off_1
.
However in this line:
off_t off_2 = sizeof(long);
sizeof(long)
is a compile time constant (8
on your system), and the compiler can verify that it can be safely assigned into off_t off_2
.
OT: You can probably see the same with simpler code without use of
sizeof
. Trysize_t sz = 8; off_t off_1 = sz; off_t off_2 = (size_t)8;