Is Misra-C compatible with X-macros?
Asked Answered
W

2

7

It could be argued that in many cases X-macros increase safety, because it makes easier to make sure that generated arrays are the same length for example.


However, Misra C (from 2004 reference) rules seem to have a lot of preprocessor rules that restrict the usage:

Rule 19.1 (advisory) #include statements in a file should only be preceded by other preprocessor directives or comments.

Troublesome if source table is in other file which is included to generate array for example. But this is advisory rule so it can be worked around.

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

Should not be issue since most X-macros are used to generate array initializers or constants.

Rule 19.6 (required) #undef shall not be used.

Makes some X-macro usage patterns impossible. Unfortunate, but doesn't outright prevent X-macros.

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

Advisory rule only.

Rule 19.12 (required) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro definition.

Can be worked around using nested macros.

Rule 19.13 (advisory) The # and ## preprocessor operators should not be used.

Troublesome when generating enums for example, but again this is only advisory rule.

Rule 19.15 (required) Precautions shall be taken in order to prevent the contents of a header file being included twice.

Troublesome in some scenarios, but can be worked around.


Looking at the above, it seems that it is possible to use X-macros with Misra C code, if you are careful.

Is my conclusion correct, or is there some rule I am missing?

William answered 27/9, 2018 at 8:1 Comment(2)
Does 19.4 mean expand immediately or is expansion via another macro also acceptable? That could potentially be the non-starter.Livvyy
@StoryTeller Good point. I assumed it listed the final result after all preprocessing, but I don't know for sure.William
P
6

Using X-macros to increase type safety is in my opinion a rather weak argument. The main thing they do is to ease maintenance and eliminate problems with code repetition. But like any function-like macros, they are the last resort when everything else fails.

The proper way to ensure that arrays are of the correct lengths etc is to use static_assert (or some hack:ish pre-C11 mechanism) that yields a compile-time error.

Addressing your concerns one at a time:

  • include statements in a file should only be preceded by other preprocessor directives or comments. ... Troublesome if source table is in other file which is included...

    This is a sound rule and there is no reason to deviate from it. If you have a source table in another file which you #include, then what's the problem? The rule doesn't speak of the pre-processed header file.

    The main reason for the rule is to prevent people from tossing in #include in the middle of a file somewhere. (Which is most likely caused by some left-over debug code.)

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

    If interpreted as the (recursively) expanded macros, it shouldn't be a problem, since X macros should boil down to constants, types etc in the end. The rule says "expand" so my take is that it refers to the fully expanded macros.

    This rule has been dropped entirely in MISRA-C:2012 and replaced with other more specific rules, such as not making macros with the same name as a language keyword etc.

  • Rule 19.6 (required) #undef shall not be used.

    This rule has been relaxed in MISRA-C:2012, from required to advisory. One valid argument raised against the rule is indeed that #undef is necessary for X-macros, though I can't say if this is why it was relaxed.

    Mostly the rule is there to prevent code like #undef NULL or other strange and obscure ideas some people might get.

  • Rule 19.7 (advisory) A function should be used in preference to a function-like macro.

    In general, MISRA-C is against using function-like macros, this is an advisory rule in both MISRA-C:2004 and the current MISRA-C:2012. And for very good reasons: we all know that function-like macros in general are evil, but we also know that they are often a necessary evil.

  • Rule 19.12 (required) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro definition.

    This rule has been relaxed in MISRA-C:2012 to advisory. It might be hard to write some X macros without these two. There are a couple of valid dangers associated with them, but that's addressed by other rules. I see no conflict with X macros in MISRA-C:2012.

  • Rule 19.15 (required) Precautions shall be taken in order to prevent the contents of a header file being included twice.

    Sound rule that enforces the use of header guards. There should be no reason to deviate from it, with or without X macros.

Conclusion:
You cannot use X macros in the previous MISRA-C:2004, but you can use them in the current MISRA-C:2012. I would strongly recommend to upgrade, since MISRA-C:2012 is a major change for the better. Various pedantic rules have been dropped, relaxed or re-written. Complicated rules like the ones regarding implicit type promotions have been significantly improved. There is now C99 support. And so on.

I have used X-macros myself with MISRA-C:2012, and as far as I remember, without the need to raise deviations from any required rules.

Pancho answered 27/9, 2018 at 9:50 Comment(1)
Re-visiting this... X-macros in the form of #define LIST_OF_STUFF(X) \ X(...) are invoked with LIST_OF_STUFF(SOME_MACRO) rather than LIST_OF_STUFF(X). This means that we don't have to re-define this magic "X" all the time. The code turns more flexible and we don't need to use #undef.Pancho
C
0

Please remember that MISRA-C:2004 is a set of Guidelines... it even gives you a process to follow in event that you want to do something that the Guidelines say don't.

Looking at the above, it seems that it is possible to use X-macros with Misra C code, if you are careful.

Yes... you can raise a Deviation - this requires you to understand the consequences of your decision to violate a Guideline, to justify that violation, and to gain appropriate approval.

In which case, Deviate away.

Camelot answered 28/9, 2018 at 10:55 Comment(1)
As per my answer, my conclusion is that no deviations should be necessary, since "X-macros" only break advisory rules. This assuming MISRA-C:2012, which allows #undef.Pancho

© 2022 - 2024 — McMap. All rights reserved.