【问题标题】:MISRA rule 13.6 explanation neededMISRA 规则 13.6 需要解释
【发布时间】:2016-04-09 11:50:30
【问题描述】:

规则 13.6 规定: sizeof() 运算符的操作数不应包含任何
具有潜在副作用的表达式。我无法确定运算符如何
有副作用会影响 sizeof() 运算符的结果。
谁能用这个例子解释一下?

void f(int32_t n)
{
    size_t s;
    s = sizeof(int32_t[n]); //Compliant
    s = sizeof(int32_t[n++]); //Non Compliant
}

或者任何人都可以举一个更容易理解的例子并用它来解释吗?

【问题讨论】:

    标签: c lint misra


    【解决方案1】:

    不计算输入到sizeof 运算符的表达式。仅推导出表达式的类型并将其用作sizeof 运算符的输入。这意味着,在不符合 MISRA 的情况下,n++n 不会递增。由于这有点违反直觉,MISRA 建议不要使用具有副作用的表达式以避免错误。

    【讨论】:

    • s/不合规案例/合规案例/
    • @wildplasser 我觉得它是正确的。不合规的情况是具有后增量运算符的情况,其中违反直觉的 n 不会递增。
    • 这可能有点模棱两可。 "[non] compliant" := 符合标准,或符合MISRA
    • 这两种情况都不符合 C 标准。第二个是 MISRA,如示例代码中的注释所述。但是好的,我会澄清的。
    • 它实际上由所有主要的 C99 编译器递增。见godbolt.org/z/5E79xje64
    【解决方案2】:

    sizeof 运算符是一种特殊情况,通常它只在编译时计算并被一个常量替换。这意味着sizeof 的操作数内的任何副作用(“代码”)实际上都不会被执行。此类错误的示例:

    sizeof(i++) // Bad! i will not get incremented
    sizeof(i=j) // Bad! i will not get a new value
    sizeof(func()) // Bad! The function will not get called
    

    (在运行时计算sizeof 时有一个例外,即当操作数是可变长度数组类型时。)

    MISRA 文档提供了一个很好的理由来解释所有这些。如果您阅读细则,volatile 变量甚至会有一个例外,因为表达式中仅存在这样的变量就会产生副作用(读取变量)。

    【讨论】:

    • 是的,我还记得 volatile 的例外情况。但是无法完全了解这种副作用。感谢您的帮助。
    • @NishrinTrunkwala C 标准 5.1.2.2.3 中对术语副作用有正式定义“访问 volatile 对象、修改对象、修改文件或调用执行任何操作的函数这些操作都是副作用,“
    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多