Will this kind of construct would need a deviation from MISRA C 2012, and 2020?
#include <stdio.h>
#define ONE 1
#define TWO 2
#define OOPS 42
#define INNER_DEF_BAR(x) (bar_##x)
#define DEF_BAR(x) void INNER_DEF_BAR(x)(void)
DEF_BAR(ONE);
DEF_BAR(TWO);
DEF_BAR(OOPS);
DEF_BAR(ONE)
{
printf("one\n");
}
DEF_BAR(TWO)
{
printf("two\n");
}
DEF_BAR(OOPS)
{
printf("42\n");
}
int main()
{
bar_1();
bar_2();
bar_42();
return 0;
}
For instance, in MISRA C 2012, I'm confused with the following sentence
Rule 20.7 Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses
and the conclusion of this thread about X-macros beeing possible without deviation because breaking only advisory rules.
CodePudding user response:
Using macros in order to declare/define functions is incredibly questionable practice in any system, particularly a critical one. This is not explicitly a (mandatory/required) MISRA violation as far as I can tell, but there is just no way code like this will pass any code review, let alone any half-decent functional safety assessor. There are few ways to aggravate code reviewers more than to invent My Little Macro Languagetm and then forcing them to learn it.
From a strict MISRA C perspective, you are violating advisory Directive 4.9 about using function-like macros and advisory Rule 20.10 regarding use of the ##
operator. It is true that you need no formal deviation for breaking advisory rules, but you still need to make an argument regarding why you are doing so. Ideally this should be on a company coding guideline level, stating which advisory rules that are ignored and which advisory rules that are enforced. That is, either you'll filter out a certain advisory rule from all static analysis, or you'll "promote it" and treat it just like any Required rule.
X macros and function-like macros are questionable in general, but you can use them in a structured "de facto standard" way. It's possible to make an argument why they would improve code under specific scenarios.
I sincerely doubt that you can make a sound argument for why function name generation should be done with function-like macros in a critical program though. Such a program must be deterministic with no surprises hidden behind macros. In particular there should be no type-generic or "template" programming allowed. So IMO there are only two proper solutions:
- Remove the macros and just type out/hardcode everything, or
- Remove the macros and pre-generate the source code using a script that runs before compilation and static analysis.
Anything else is highly questionable.