size_t与-1比较的合法性探讨:Microchip库代码疑问
size_t类型函数返回-1时的比较合法性问题
说明:曾有人认为本问题与《Can I compare int with size_t directly in C?》重复,但本问题专门针对size_t与负值的比较,因此应重新开放。(此外,本问题已引发诸多深入讨论!)
我看到Microchip的某段库代码,其声明返回size_t类型:
size_t SYS_FS_FileWrite(SYS_FS_HANDLE handle, const void *buf, size_t nbytes);
文档说明该函数错误时返回-1,但size_t是无符号类型。那么从理论和实践层面,以下写法是否被允许?
if (SYS_FS_FileWrite(handle, buf, nbytes) == -1) { report_errror(); }
理论层面
按照C语言的类型转换规则,当无符号类型(size_t)和有符号常量-1进行比较时,-1会被隐式转换为无符号类型。这个转换的结果是size_t类型的最大值(比如32位系统下为0xFFFFFFFF,64位系统下为0xFFFFFFFFFFFFFFFF),也就是标准头文件<stddef.h>中定义的SIZE_MAX。
而函数返回的错误值-1,由于函数返回类型是size_t,实际返回的就是这个无符号最大值(将有符号的-1赋值给无符号变量时会执行同样的转换)。所以从语法和语义上来说,返回值 == -1的比较完全符合C标准,是合法的,本质等价于返回值 == SIZE_MAX。
实践层面
- 绝大多数编译器都能正确处理这种转换,不会触发编译错误;但如果开启了严格的类型检查警告(比如GCC的
-Wsign-compare),会提示有符号与无符号类型比较的问题。 - Microchip的库文档明确说明错误时返回
-1,说明他们预期开发者采用这种写法,在他们的目标平台上是完全可行的。 - 不过从代码可读性和严谨性角度,更推荐显式写成
== SIZE_MAX:这样能直接表达判断无符号类型最大值的意图,避免其他开发者产生误解,同时也能消除严格编译模式下的警告。
内容的提问来源于stack exchange,提问作者fearless_fool
相关产品推荐
相关产品推荐

