是 cppcheck 的误报 containerOutOfBoundsIndexExpression 错误吗?

Posted

技术标签:

【中文标题】是 cppcheck 的误报 containerOutOfBoundsIndexExpression 错误吗?【英文标题】:Is it false positive containerOutOfBoundsIndexExpression error of cppcheck? 【发布时间】:2020-12-15 19:42:26 【问题描述】:

我想用 cppcheck 工具检查以下代码:

void f()

    std::string str = "123";
    const char* end = &str[str.size()];

但是当我运行 cppcheck 时,它会报告以下我认为是误报的错误:

$ cppcheck oob.cpp
Checking oob.cpp ...
oob.cpp:4:27: error: Out of bounds access in 'str[str.size()]', if 'str' size is 3 and 'str.size()' is 3 [containerOutOfBounds]
    const char* end = &str[str.size()];
                          ^
oob.cpp:4:24: error: Out of bounds access of str, index 'str.size()' is out of bounds. [containerOutOfBoundsIndexExpression]
    const char* end = &str[str.size()];
                       ^

据我了解,std::string 应存储终止空字符以及字符串的其余字符,因此 str[str.size()] 应返回 0 字符,但 cppcheck 返回错误。是cppcheck误报吗?

【问题讨论】:

因为在使用en.cppreference.com/w/cpp/string/basic_string/c_str 获取C 字符串时,它应该以null 结尾。如果std::string 返回指向内部缓冲区的指针,则零终止符应该已经在该缓冲区中。 【参考方案1】:

我认为这是误报。我创建了这张票:https://trac.cppcheck.net/ticket/10048

【讨论】:

【参考方案2】:

基于Will std::string always be null-terminated in C++11?,该标准保证std::string 是[内部] 0-终止的。

但是,这不允许您直接引用 0,因此 cppcheck 在技术上是正确的。

更新

正如 Thomas 在评论中指出的那样,您实际上可以引用 0 终止符 SINCE C++ 11。

cppcheck 有一个符合特定标准的设置:--std=<id> (https://linux.die.net/man/1/cppcheck)

看看这是否会改变它的行为。

【讨论】:

不,cppcheck --std=c++11 不会改变任何东西。 --std=c++11 也是 cppcheck 中的默认值,因此没有任何选项的普通 cppcheckcppcheck --std=c++11 相同,请参阅 linux.die.net/man/1/cppcheck。

以上是关于是 cppcheck 的误报 containerOutOfBoundsIndexExpression 错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

“每个窗口的误报”的含义

cppcheck 报告误报

如何避免 SQL 查询检查 IS NULL 的误报?

如何修复线性 SVM 的误报率?

Swift5.4 中可选的误报

IntStream 何时真正关闭? SonarQube S2095 是 IntStream 的误报吗?