Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.DEFINE.BADEXP

Inappropriate macro expansion.

MISRA-C Rule 19.4 (required): C macros shall only expand to a braced initialiser, a constant, a string literal, a parenthesised expression, a type qualifier, a storage class specifier, or a do-while-zero construct.

[Koenig 82—84]

These are the only permitted uses of macros. Storage class specifiers and type qualifiers include keywords such as extern, static and const. Any other use of #define could lead to unexpected behaviour when substitution is made, or to very hard-to-read code.

In particular macros shall not be used to define statements or parts of statements except the use of the do-while construct. Nor shall macros redefine the syntax of the language. All brackets of whatever type ( ) { } [ ] in the macro replacement list shall be balanced.

The do-while-zero construct (see example below) is the only permitted mechanism for having complete statements in a macro body. The do-while-zero construct is used to wrap a series of one or more statements and ensure correct behaviour. Note: the semicolon must be omitted from the end of the macro body.

Example

/* The following are compliant */
#define PI 3.14159F                   /* Constant                      */
#define XSTAL 10000000                /* Constant                      */
#define CLOCK (XSTAL/16)              /* Constant expression           */
#define PLUS2(X) ((X) + 2)            /* Macro expanding to expression */
#define STOR extern                   /* storage class specifier       */
#define INIT(value){ (value), 0, 0}   /* braced initialiser            */
#define CAT (PI)                      /* parenthesised expression      */
#define FILE_A "filename.h"           /* string literal                */
#define READ_TIME_32() \
   do { \
      DISABLE_INTERRUPTS (); \
      time_now = (uint32_t)TIMER_HI << 16; \
      time_now = time_now | (uint32_t)TIMER_LO; \
      ENABLE_INTERRUPTS (); \
   } while (0) /* example of do-while-zero */
/* the following are NOT compliant */
#define int32_t long /* use typedef instead                     */
#define STARTIF if(  /* unbalanced () and language redefinition */
#define CAT PI       /* non-parenthesised expression            */