不可依赖不会生效的副作用
10.2.1 ID_unevaluatedSideEffect
有些运算符只关注类型,其子表达式不会被求值,子表达式的副作用也不会有实际效果。
这类运算在 C 语言中有:
sizeof、_Alignof、_Generic
在 C++ 语言中有:
sizeof、typeid、noexcept、decltype、declval
这类运算符不宜作用于逻辑、算术、位运算、函数调用等表达式。
特殊情况:
- 在 C 语言中,如果 sizeof 作用于变长数组类型,数组长度表达式是否会被求值是标准未声明的
- 在 C++ 语言中,如果 typeid 作用于多态类型的“泛左值(glvalue)”,该泛左值会被求值
虽然在某些特殊情况下相关子表达式会被求值,但为了避免意料之外的错误,本规则要求这类运算符的子表达式在任何情况下均不可含有任何副作用。
示例:
int a = 0;
int b = sizeof(a++); // Non-compliant
printf("%d ", a);
int c = sizeof(int[a++]); // Non-compliant, variable length array
printf("%d\n", a);
sizeof(a++) 的副作用不生效,而 sizeof(int[a++]) 的副作用可能会生效,这往往会使人困惑。
相关
依据
ISO/IEC 9899:1999 6.5.3.4(2)
ISO/IEC 9899:1999 6.7.5.2(5)-unspecified
ISO/IEC 9899:2011 6.5.3.4(2)
ISO/IEC 9899:2011 6.7.6.2(5)-unspecified
ISO/IEC 14882:2003 5.3.3(1)
ISO/IEC 14882:2011 5.3.3(1)
ISO/IEC 14882:2017 8.3.3(1)
参考
MISRA C 2004 12.3
MISRA C 2012 13.6
MISRA C++ 2008 5-3-4
SEI CERT EXP44-C
SEI CERT EXP52-CPP