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.FUNC

Function-like macro definition.

MISRA C 2012 Dir 4.9 :A function should be used in preference to a function-like macro where they are interchangeable

Category: Advisory

Applies to: C90, C99

Amplification

This guideline applies only where a function is permitted by the syntax and constraints of the language standard.

Rationale

In most circumstances, functions should be used instead of macros. Functions perform argument type-checking and evaluate their arguments once, thus avoiding problems with potential multiple side effects. In many debugging systems, it is easier to step through execution of a function than a macro. Nonetheless, macros may be useful in some circumstances. Some of the factors that should be considered when deciding whether to use a function or a macro are:

  • The benefits of function argument and result type-checking;
  • The availability of inline functions in C99, although note that the extent to which inline is acted upon is implementation-defined;
  • The trade-off between code size and execution speed;
  • Whether the possibility for compile-time evaluation is important: macros with constant arguments are more likely to be evaluated at compile-time than corresponding function calls;
  • Whether the arguments would be valid for a function: macro arguments are textual whereas function arguments are expressions;
  • Ease of understanding and maintainability

Example

The following example is compliant. The function-like macro cannot be replaced with a function because it has a C operator as an argument:

#define EVAL_BINOP( OP, L, R ) ( ( L ) OP ( R ) )

uint32_t x = EVAL_BINOP ( +, 1, 2 );

In the following example, the use of a macro to initialize an object with static storage duration is compliant because a function call is not permitted here.

#define DIV2(X) ( ( X ) / 2 )

void f ( void ) 
{
  static uint16_t x = DIV2 ( 10 );    /* Compliant - call not permitted */ 
         uint16_t y = DIV2 ( 10 );    /* Non-compliant - call permitted */ 
}

See also

Rule 13.2, Rule 20.7

MISRA-C Rule 19.7 (advisory): A function should be used in preference to a function-like macro

[Koenig 78—81]

While macros can provide a speed advantage over functions, functions provide a safer and more robust mechanism. This is particularly true with respect to the type checking of parameters, and the problem of function-like macros potentially evaluating parameters multiple times.

MISRA-C++ Rule 16-0-4 (required): Function-like macros shall not be defined.

[Undefined 16.3(10)]

Rationale

While macros can provide a speed advantage over functions, functions provide a safer and more robust mechanism. This is particularly true with respect to the type checking of parameters, and the problem of function-like macros potentially evaluating parameters multiple times.

Inline functions should be used instead.

Example

#define FUNC_MACRO(X) ((X)+(X)) // Non-compliant