不应出现非标准格式的预编译指令
3.4.2 ID_illFormedDirective
非标准格式的预编译指令往往意味着错误,也会导致标准未定义的行为。
需注意:
- defined 只应作用于宏名称或括号括起来的宏名称
- defined 不应出现在宏定义中
- #if、#elif 之后应为正确的常量表达式
- #ifdef、#ifndef 之后只应为宏名称
- #else、#endif 之后应直接换行
- #line 之后应接整数常量,或整数常量和文件名称
- #line 指定的行号应在有效范围内
- #line 不应出现在非自动生成的代码中
示例:
#if defined M // Compliant
#if defined(M) // Compliant
#if defined(M == 0) // Non-compliant, undefined behavior
#define DEFINED defined // Non-compliant
#if DEFINED M // Undefined behavior
#line 0 // Non-compliant, invalid line number
#line 4294967295 // Non-compliant, line number too large
例中作用于比较表达式的 defined 和 #if 条件中由宏展开产生的 defined 均会导致未定义的行为,由 #line 指定的行号应大于 0 且小于 2147483648(按 C++03 标准则应小于 32768),否则也会导致未定义的行为。
又如:
#define M 2
int foo() {
int x = 0;
#ifdef M
x = M;
#elif // Non-compliant, use ‘#else’ instead
x = 1;
#endif M // Non-compliant, remove ‘M’
return x;
}
这种代码是不符合标准的,但可被某些编译器接受,应避免。
依据
ISO/IEC 9899:1999 6.10(1)
ISO/IEC 9899:1999 6.10.1(3)-undefined
ISO/IEC 9899:2011 6.10(1)
ISO/IEC 9899:2011 6.10.1(4)-undefined
ISO/IEC 14882:2003 16.1(4)-undefined
ISO/IEC 14882:2003 16.2(4)-undefined
ISO/IEC 14882:2003 16.4(3)-undefined
ISO/IEC 14882:2003 16.4(5)-undefined
ISO/IEC 14882:2011 16.1(4)-undefined
ISO/IEC 14882:2011 16.2(4)-undefined
ISO/IEC 14882:2011 16.4(3)-undefined
ISO/IEC 14882:2011 16.4(5)-undefined
参考
MISRA C++ 2008 16-0-7
MISRA C++ 2008 16-0-8
MISRA C++ 2008 16-1-1