☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

不可臆断返回值的意义

10.6.2 ID_wrongUseOfReturnValue
目录 › next › previous

应遵循接口文档使用接口,不可臆断返回值的意义,否则造成逻辑错误。

示例:

void foo(const string& s) {
    if (s.find("bar")) {      // Non-compliant
        ....
    }
}

例中 find 函数返回 "bar" 在 s 中的位置,当 s 中不存在 "bar" 时返回 string::npos,将 find 函数的返回值转为 bool 型是没有逻辑意义的。

应改为:

void foo(const string& s) {
    if (s.find("bar") != string::npos) {   // Compliant
        ....
    }
}

想当然地认为返回 0 表示失败或不存在,非 0 表示成功或存在,是造成错误的常见原因。

又如:

bool gt(const char* a, const char* b) {
    return strcmp(a, b) == 1;             // Non-compliant
}

strcmp 函数的返回值可以是等于、大于或小于 0 的任意整数,分别对应字符串的等于、大于或小于关系,认为其只能返回 0、1 或 -1 是一种常见的误解。

应改为:

bool gt(const char* a, const char* b) {
    return strcmp(a, b) > 0;              // Compliant
}

strcmp、wcscmp 以及 memcmp 等函数不应与 0 之外的任何值比较。

下列函数的返回值不应与 0 比较,也不应转为 bool 型:

  • open、create 等 Linux 系统调用,失败时返回负数,成功时返回非负数
  • CreateFile、CreateNamedPipe 等 Windows API,失败时返回 INVALID_HANDLE_VALUE,而不是 0
  • HRESULT 型 Windows API 返回值,负数表示失败、非负数表示成功

另外,有相当一部分函数成功时返回 0,失败时返回非 0,如 access、chmod、rename 等 Linux 系统调用,不可将其返回值当作 bool 型使用。

依据

ISO/IEC 9899:1999 7.21.4 ISO/IEC 9899:2011 7.24.4

参考

CWE-253
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.