gpt4 book ai didi

c++ - 如何指定符合 MISRA C++ 的字 rune 字?

转载 作者:行者123 更新时间:2023-12-02 10:04:25 26 4
gpt4 key购买 nike

我正在组织 Klocwork 规则并清除静态分析发现的任何问题。应用了多个规则,目前我在指定字 rune 字时遇到问题。
让我们考虑这个例子:

for (const char* p = str; *p != '\0'; ++p)

如您所见,这是对 C-String 进行迭代的循环。它用于利用 constexpr 字符串文字的 unordered_map。性能测量证明,将它们存储为 std::string 会增加内存使用量并由于开销而影响性能。由于此映射内容是恒定的,因此我对 C 字符串使用自定义散列仿函数(再次,避免转换并将字符串复制到 std::string 以生成散列)。简单的答案是使用 std::string_view 但它在此环境中不可用。
所以问题来自条件本身。条件应检查字符是否终止为空。

显然一开始我用了 !p因为它由标准保证,终止 null 解析为 false(无论字符的真实类型是什么)。它导致 AUTOSAR C++14 (18-03) 错误 MISRA.STMT.COND.NOT_BOOLEAN这意味着“if 或循环语句的条件类型为‘char’而不是‘boolean’”。

好的,我将其更改为显式比较 p != 0结果是 MISRA.CHAR.NOT_CHARACTER “'char' 用于非字符值”的违规行为。

同样,这是有效的一点,因为我将 char 与 int 进行比较,但 char 既不是 int 也不是 unsigned int。所以我把它改成了 *p != '\0'这应该直接转换为空字符。这反过来又给出了 MISRA.LITERAL.UNSIGNED.SUFFIX违规是“无符号整数文字 ''\0'' 没有 'U' 后缀”。现在我很惊讶。即使 char 在一个编译器中被认为是无符号的,也不能保证它是有符号的或无符号的,所以我不能将它硬编码为任何符号。甚至没有提到似乎没有办法为字 rune 字指定后缀。在我看来,它已经是误报了 '\0' IS char 类型,不需要任何进一步的转换或强制转换。这显示了像 uri.find_last_of('/') 这样的语法更明显的问题。我正在寻找特定的角色,而不是特定的值(value)。这种情况会产生同样的错误,提示我没有指定后缀。 (uri 是 std::string)

我的猜测是,这是错误的过滤器实现的误报。此外,似乎静态分析可能被错误配置,因为字 rune 字仅在 C 中被认为是整数,而不是在 C++ 中。

作为旁注,我将在第一个示例中使用 *p != char(0) 添加它解决了这个问题,但这远不是首选的解决方案,只能与已知的字符整数值一起使用,这远不如使用文字灵活且容易出错,因此我不打算使用这种解决方法。

你对这个问题有什么想法?也许其他人已经遇到了这样的 Klocwork 错误,并找到了除禁用规则或为每个文字字符实例抑制规则之外的解决方案。我已经有了我的常见误报列表,这些误报通常来自 C++11 和基于 MISRA 2008 C++ 的规则检查的更新标准。

最佳答案

Obviously at first I used !p as it's guaranteed by standard that terminating null resolves to false



是的,但 MISRA 规则超出了标准。考虑类似 char* ptr = 0; if(ptr) 的内容.在 if(ptr)之间很容易滑倒和 if(*ptr)这是错误的常见来源。无论代码是正确的还是错误的,读者无法仅从那一行就知道程序员的意图。

同样, ptr != 0 的意图是什么? ?检查指针是否为 NULL 或指向的数据是否为零,或者数据是否特别是字符串末尾的空终止符?

因此,MISRA 强制执行显式检查。代码如 if(ptr != NULL)if(*ptr != '\0')是 MISRA 的建议,这里程序员的意图非常明确。

你的问题到处都是这个问题!您输入 *p在某些地方和 p在某些地方。 const char* p = str; ... p != '\0'显然是一个错误,如果那是您的实际代码,那么 MISRA 只是将您从它中救了出来。

Therefore I changed it to p != '\0' which should directly translate to null character.



事实上,这是符合 MISRA 的代码。再次假设 pchar而不是 char* .

This in turn gives MISRA.LITERAL.UNSIGNED.SUFFIX violation which is "Unsigned integer literal ''\0'' without the 'U' suffix".



那是胡说八道。 '\0'是一个字符常量,类型为 char在 C++ 中。您的工具必​​须将其与常规整数常量(十进制、八进制或十六进制)混淆,其中 U如果打算在无符号算术中使用它们,则需要后缀。

现在 MISRA 普遍对八进制转义序列不屑一顾,但在 MISRA-C:2004 中,很多人(包括你们真诚地)向委员会指出 \0必须是一个有效的异常(exception)。这是固定的和 \0已在 2007 年 7 月发布的 MISRA-C:2004 TC1 中生效。我不确定该修复程序是否已进入原始 MISRA-C++:2008,或者是否也有适用于 MISRA-C++ 的 TC。

无论如何,使用 '\0'因为空终止符很好并且符合 MISRA。只要你只用它和其他的比较 char类型操作数。

关于c++ - 如何指定符合 MISRA C++ 的字 rune 字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60984000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com