Our website uses cookies to enhance your browsing experience.
Accept
to the top
>
>
>
V2668. MISRA. The macro parameter...
menu mobile close menu
Additional information
toggle menu Contents

V2668. MISRA. The macro parameter immediately following a '#' operator should not immediately be followed by a '##' operator.

Feb 05 2026

This diagnostic rule is based on the MISRA (Motor Industry Software Reliability Association) software development guidelines.

This diagnostic rule is relevant only for C.

A macro parameter preceded by the # operator should not be followed by the ## operator. Using such a replacement in a function-like macro can form an invalid preprocessing token and result in undefined behavior.

The # and ## operators prevent expansion of their operands, which are defined in the replacement list. The # operator results in a string literal, while the ## operator concatenates its left and right operands. It is highly unlikely that concatenating a string literal with a preprocessing token produces another valid token.

The example:

#include <stdio.h>

#define my_print(a, b) printf("%s", #a ## b)

#define HELLO "hello"
#define WORLD "world"
#define HELLOWORLD "hello, world"

int main(int argc, char *argv[])
{
  my_print(HELLO, WORLD);
  return 0;
}

The concatenation of tokens within the my_print macro results in the "HELLO"WORLD token, which is passed as an argument to the printf function. This token is not valid, and the behavior in this case is undefined. Compilers such as GCC and Clang do not compile this code, while MSVC compiles it successfully and outputs HELLOworld.

The developer might have intended to concatenate the HELLO and WORLD macro names to get the HELLOWORLD token, which the preprocessor then expands into the string literal "hello, world":

#include <stdio.h>

#define my_print(a, b) printf("%s", a ## b)

#define HELLO "hello"
#define WORLD "world"
#define HELLOWORLD "hello, world"

int main(int argc, char *argv[])
{
  my_print(HELLO, WORLD);
  return 0;
}

Now the preprocessor concatenates HELLO and WORLD into HELLOWORLD. When rescanning, this token expands into the string literal "hello, world", which is then passed as an argument to the printf function.

Note. Using the sequence ## followed by # in reverse order is allowed. For example, such a macro can be used to form wide string literals:

#define GET_WIDE_STR(a, b) a ## #b

int main(int argc, char *argv[])
{
  GET_WIDE_STR(L, raw_string_literal);
  return 0;
}

/* Results in:

int main(int argc, char *argv[])
{
  L"raw_string_literal";
  return 0;
}

*/

This diagnostic is classified as:

  • MISRA-C-2012-20.11
  • MISRA-C-2023-20.11