米斯拉 C++规则 5-0-3 误报警告

发布于 2025-01-13 01:06:49 字数 1198 浏览 1 评论 0原文

我的静态分析器抛出以下警告:

MCPP 规则 5-0-3:这个复杂的表达式被隐式转换为 不同的基本类型

以下代码的

void func(const uint32_t arg)
{
    //32U has underlying type uint8_t
    const uint32_t u32a = arg % 32U; //warning issued in this line
    const uint32_t u32b = (arg % static_cast<uint32_t>(32U)); //same warning issued in this line
    const uint32_t u32c = static_cast<uint32_t>(arg % 32U); //compliant
}

:根据 MISRA 底层类型转换规则:

否则,如果两个操作数都是整型,则其基础类型 可以使用以下命令找到表达式:

– 如果类型 操作数大小相同,并且其中一个是无符号的,结果是 未签名。

– 否则,结果的类型是较大的类型 类型。

我认为此警告可能是误报,因为尽管 32Uuint8_t,但表达式应采用较大类型的基础类型,在本例中为 >uint32_t,因此不需要 static_cast

您是否同意这是误报?还是我看错了?

编辑: MISRA 标准规定:

因此,整数常量表达式的基础类型是 定义如下:

  1. 如果表达式的实际类型是有符号整数,则基础类型定义为最小有符号整数类型 能够体现其价值。

  2. 如果表达式的实际类型是无符号整数,则基础类型定义为满足以下条件的最小无符号整数类型: 能够体现其价值。

  3. 在所有其他情况下,表达式的基础类型被定义为与其实际类型相同。

第二点是我必须假设 32U 具有 uint8_t 底层类型的原因。

My static analyzer is throwing the following warning:

MCPP Rule 5-0-3: This complex expression is implicitly converted to a
different essential type

for the following code:

void func(const uint32_t arg)
{
    //32U has underlying type uint8_t
    const uint32_t u32a = arg % 32U; //warning issued in this line
    const uint32_t u32b = (arg % static_cast<uint32_t>(32U)); //same warning issued in this line
    const uint32_t u32c = static_cast<uint32_t>(arg % 32U); //compliant
}

According to MISRA underlying type conversion rules:

Otherwise, if both operands have integral type, the underlying type of
the expression can be found using the following:

– If the types of the
operands are the same size, and either is unsigned, the result is
unsigned.

– Otherwise, the type of the result is that of the larger
type.

I think this warning may be a false positive because, despite the 32U being a uint8_t, the expression should take the underlying type of the larger type, in this case the uint32_t, thus making the need for the static_cast unnecessary.

Do you agree this is a false positive? Or am I looking at it all wrong?

EDIT:
The MISRA standard states that:

The underlying type of an integer constant expression is therefore
defined as follows:

  1. If the actual type of the expression is signed integral, the underlying type is defined as the smallest signed integer type that is
    capable of representing its value.

  2. If the actual type of the expression is unsigned integral, the underlying type is defined as the smallest unsigned integer type that
    is capable of representing its value.

  3. In all other circumstances, the underlying type of the expression is defined as being the same as its actual type.

No. 2 is the reason why I've to assume that 32U has the underlying type of uint8_t.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

坦然微笑 2025-01-20 01:06:49

我认为此警告可能是误报,因为尽管 32Uuint8_t

32U 不是 uint8_t在任何平台上。对于整数文字,您可以表达的最小类型是 int/unsigned int根据cppreference nnnnU即可
unsigned intunsigned long intunsigned long long int。它确实选择了第一个可以存储文字的类型,因此 32U 是一个 unsigned int

因此,如果您想保证 32U 与 uint32_t 的类型相同,那么您需要在右侧进行强制转换。

I think this warning may be a false positive because, despite the 32U being a uint8_t

32U is not a uint8_t on any platform. With integer literals the smallest type you can express is a int/unsigned int. According to cppreference nnnnU can be
a unsigned int, unsigned long int, or unsigned long long int. It does pick the first type that the literal can be stored in so 32U is a unsigned int.

So if you want to guarantee that 32U is the same type as uint32_t then you need the cast on the right hand side.

只等公子 2025-01-20 01:06:49

32U 的类型为 unsigned,它可能与 uint32_t 不同。与您的声明相反,它永远不是 uint8_t 类型

unsigned 仅保证能够表示 00 范围内的值code>65535,尽管允许支持更大的范围。它实际上可以代表什么是实现定义的。但是,它不能是 uint8_t,因为 uint8_t 无法表示 unsigned 所需的范围。

这实际上意味着三种可能性:unsigned 可能是 16 位类型、32 位类型,甚至是 64 位类型 - 并且它们分别较小、大小相同,或大于uint32_t

因此,表达式 arg % 32U 的结果可能是 uint32_t 类型(如果 unsigned 是 16 位),uint32_t code> (如果 unsigneduint32_t 都是相同的 32 位类型),或 unsigned (如果unsigned 是 64 位类型)。在最后一种情况下,需要从 unsigneduint32_t 的转换来初始化 u32a

您的静态分析器正在警告您系统之间潜在的行为差异。

所以,不,这不是误报。

32U is of type unsigned, which is potentially a distinct type from uint32_t. Contrary to your statement, it is never of type uint8_t

A unsigned is only guaranteed to be able to represent the values in the range 0 to 65535, although it is permitted to support a larger range. What it actually can represent is implementation-defined. However, it cannot be a uint8_t, since a uint8_t cannot represent the range required of an unsigned.

This means, practically, three possibilities are that unsigned may be a 16-bit type, a 32-bit type, or even a 64-bit type - and these are, respectively, smaller, the same size, or larger than a uint32_t.

The result of the expression arg % 32U may therefore be of type uint32_t (if unsigned is 16-bit), uint32_t (if unsigned and uint32_t are both the same 32-bit type), or unsigned (if unsigned is a 64-bit type). In the last case, a conversion from unsigned to uint32_t is required to initialise u32a.

Your static analyser is warning you of this potential variation of behaviours between systems.

So, no, it is not a false positive.

别闹i 2025-01-20 01:06:49

您已找到相关部分。文字所在表达式的类型是无符号的,因此底层类型是可以容纳无符号值32的最小类型,即uint8_t.如果文字是没有 U 后缀的 32,它将具有完全相同的基础类型(尽管这会违反其他 MISRA 规则)。

MISRA 的目的是在具体表达式 uint32_t arg; 中实现。 ... arg % 32U 永远不会发生危险的隐式转换。话虽如此,您可以安全地将文字转换为 uint32_t ,这应该会消除所有警告。确保代码中没有隐式类型提升是良好的编程实践,无论 MISRA 说什么/没有说什么。

如果静态分析器的目的只是检查一般的隐式升级,那么警告就可以了。如果静态分析仪的目的是检查 MISRA 合规性,那么它就是误报。

无论工具的用途如何,arg % static_cast(32U) 行永远不应产生任何形式的诊断。这肯定是误报。

You have found the relevant section. The type of the expression where the literal is located is unsigned, so the underlying type is the smallest one that can fit an unsigned value 32, meaning uint8_t. It would have the very same underlying type if the literal had been 32 without the U suffix (though that would violate other MISRA rules).

What MISRA is aiming for here is that in the specific expression uint32_t arg; ... arg % 32U there can never occur a dangerous implicit conversion. That being said, you can safely cast the literal to uint32_t and that should silence all warnings. Ensuring that there are no implicit type promotions in your code what-so-ever is good programming practice, no matter what MISRA says/doesn't say.

If the purpose of the static analyser is just to check for implicit promotions in general, then the warning is fine. If the purpose of your static analyser is to check for MISRA compliance, then it is a false positive.

The line arg % static_cast<uint32_t>(32U) should never yield any form of diagnostic, regardless of the purpose of the tool. That is certainly a false positive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文