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
是一个长的,但是潜在的更大的东西,并且正在使用,那么代码可以使用以下内容。