Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 错误:有符号和无符号整数表达式之间的比较_C - Fatal编程技术网

C 错误:有符号和无符号整数表达式之间的比较

C 错误:有符号和无符号整数表达式之间的比较,c,C,我在编译以下代码时遇到上述错误 long _version_tag; size_t _timing; ssize_t bytes_read = read(fd, &_version_tag, sizeof(long)); if (bytes_read < sizeof(long) || _version_tag != TIMING_FILE_VERSION_TAG) return -1; long\u版本\u标签; 大小和时间; ssize_t bytes_read=r

我在编译以下代码时遇到上述错误

long _version_tag;
size_t _timing;

ssize_t bytes_read = read(fd, &_version_tag, sizeof(long));
if (bytes_read < sizeof(long) || _version_tag != TIMING_FILE_VERSION_TAG)
    return -1;
long\u版本\u标签;
大小和时间;
ssize_t bytes_read=read(fd,&_version_标记,sizeof(long));
如果(字节数读取
gcc在这一点上抱怨:

   if (bytes_read < sizeof(long) || _version_tag != TIMING_FILE_VERSION_TAG)
                           ^
if(字节读取
我甚至尝试将读取的字节显式转换为长的字节,但没有成功。谁能帮帮我这里发生了什么事

ssize_t
是有符号类型,但sizeof的结果是
size\t
,它是无符号类型。在C语言中,如果要避免警告/错误,可以将
sizeof
结果强制转换为
ssize\t


是有符号类型,但sizeof的结果是
size\t
,它是无符号类型。在C语言中,如果想避免出现警告/错误,可以将
sizeof
结果强制转换为
ssize\t

问题在于
bytes\u read
类型为
ssize\t
有符号,而
sizeof(long)
类型为
size\u t
无符号

由于
sizeof(long)
在我能想象的任何系统上都不会太大而无法表示为
ssize\u t
,因此我建议将
sizeof(long)
的结果转换为
ssize\u t

bytes_read < (ssize_t)(sizeof(long)) // Or static_cast in C++
<代码> BythyRead <(SsiZeIt)(sisiof(long))/或静态C++中的C++


这通常只是一个警告,而不是一个错误,因为标准很好地定义了结果。但是,有符号和无符号整数类型的隐式比较可能会产生令人惊讶的结果,因此应该避免。

问题是
bytes\u read
的类型是
ssize\u t
有符号,而
sizeof(long)
的类型是
size\u t
无符号

由于
sizeof(long)
在我能想象的任何系统上都不会太大而无法表示为
ssize\u t
,因此我建议将
sizeof(long)
的结果转换为
ssize\u t

bytes_read < (ssize_t)(sizeof(long)) // Or static_cast in C++
<代码> BythyRead <(SsiZeIt)(sisiof(long))/或静态C++中的C++


这通常只是一个警告,而不是一个错误,因为标准很好地定义了结果。但是,有符号和无符号整数类型的隐式比较可能会产生令人惊讶的结果,因此应该避免。

ssize\u t
是有符号的,其中
size\u t
是无符号的。您首先需要确保
bytes\u read
为非负(表示调用没有失败)。如果该检查通过,您只需执行
bytes\u read
ssize\u t
已签名,其中
size\u t
未签名。您首先需要确保
bytes\u read
为非负(表示调用没有失败)。如果该检查通过,您只需执行
bytes\u read
如果失败,则返回-1,因此首先测试该值。如果成功,则可以测试长度。比如:

ssize_t bytes_read = read(fd, &_version_tag, sizeof(long));

if (bytes_read == -1 || (size_t)bytes_read < sizeof(long) || _version_tag != TIMING_FILE_VERSION_TAG)
    return -1;
ssize_t bytes_read=read(fd,&u version_标记,sizeof(long));
if(bytes|read==-1 | |(size|t)bytes|read
如果失败,则返回-1,因此首先测试该值。如果成功,则可以测试长度。比如:

ssize_t bytes_read = read(fd, &_version_tag, sizeof(long));

if (bytes_read == -1 || (size_t)bytes_read < sizeof(long) || _version_tag != TIMING_FILE_VERSION_TAG)
    return -1;
ssize_t bytes_read=read(fd,&u version_标记,sizeof(long));
if(bytes|read==-1 | |(size|t)bytes|read
各种答案提供了解决方案,解决了由于将比较的一侧转换为另一侧的类型而导致的警告问题。
bytes\u read

(size_t) bytes_read < sizeof(long) // or
bytes_read < (ssize_t) sizeof(long)
许多评论都反映了投机取巧的优点。施放总是有点棘手,因为存在降级施放(缩小范围)和丢失信息的可能性

在OP读取
long\u version\u tag
的示例中,没有任何区别哪一侧被转换为
long
的大小肯定小于32767-最小最大值为
ssize\u t
,小于65535-最小最大值为
size\u t


如果寻找一个通用的解决方案,并且没有假设
\u version\u tag
是一个
长的
,但是潜在的更大的东西,并且正在使用,那么代码可以使用以下内容。代码知道读取的字节中的值,如果不是-1,则必须适合大小,因为它肯定不会大于传递给read()的值

foo\u版本标签;
ssize_t bytes_read=read(fd、&u version_标记、sizeof_version_标记);
if(bytes|read==-1 | |(size|t)bytes|read
就我而言,我避免施放,更喜欢乘法以避免向下施放

if (bytes_read == -1 || ((size_t)1 * bytes_read) < sizeof _version_tag || ...)
  return -1;
if(bytes|u read==-1||(size|t)1*bytes|u read)
各种答案提供了解决方案,解决了由于将比较的一侧转换为另一侧的类型而导致的警告问题。
bytes\u read

(size_t) bytes_read < sizeof(long) // or
bytes_read < (ssize_t) sizeof(long)
许多评论都反映了投机取巧的优点。施放总是有点棘手,因为存在降级施放(缩小范围)和丢失信息的可能性

在OP读取
long\u version\u tag
的示例中,没有任何区别哪一侧被转换为
long
的大小肯定小于32767-最小最大值为
ssize\u t
,小于65535-最小最大值为
size\u t


如果寻找一个通用的解决方案,并且没有假设
\u version\u tag
是一个
长的
,但是潜在的更大的东西,并且正在使用,那么代码可以使用以下内容。