Why do the MISRA rules prohibit the use of #undef
in a program? If I want to limit the scope of any macro, how to do it without using #undef
?
3 Answers
Basically, because MISRA is too paranoid and doesn't trust programmers to know what they are doing :-) Seriously, MISRA tries to prevent certain errors and is guided by the belief that if you forbid potentially problematic code constructs, reliability of software suddenly increases. Whether that is true is a matter of debate. In the case of #undef
, the likely reason is that once a macro is defined, its expansion stays put and is always that from its definiton. If you allow #undef
, the identifier could be reused as a variable, function name, typedef or struct/union member, or even as a macro with a, gasp, different expansion. It's some way to prevent identifier shadowing, if you will. Scary, isn't it?! You decide!
To answer your second question, the only way to limit the scope of a macro if #undef
can't be used is to use the end-of-file, which is the only other standard defined way to end the scope of a macro. In other words, you have to split up your source files into smaller ones and define the macro only when compiling the particular file where it is needed.

- 69,818
- 15
- 125
- 179
-
3"Whether that is true is a matter of debate": This is a euphemism. This kind of bullcrap tends to drive good programmers away from projects (because they often have the choice to go and work somewhere else), and decreases code quality. – Alexandre C. Jul 26 '12 at 09:01
-
5As someone forced to use (a subset of) MISRA, I can wholeheartedly agree. If some ignorant management droid forced ALL of MISRAs rule to be obeyed, I'd be inclined to put heaven and hell in motion to make them understand why this is a bad idea. One way is to ask for scientific research indicating that MISRA prevents more bugs than it creates due to the contorted way to implement around its rules. – Jens Jul 26 '12 at 09:46
-
3The fact someone reads and contributes to StackOverflow already sets them apart from *most* developers. There are a huge number of 9 to 5ers who just get their code to "work". A lot of developers have never even heard of "promotion" never mind know the rules about it. Personally, I feel if you know why a rule exists and your solution better by "violating" that rule then the better code should win. It's a difficult issue though, as what's OK for my car radio is not necessarily OK for the breaking system. – Richard Corden Jul 30 '12 at 19:06
-
2@Jens MISRA-C is heavily based on scientific research, mainly by studies and books by computer scientists Les Hatton and Andrew Koenig (although none of them were in the MISRA committee). However, I don't believe either of them mentioned #undef, that particular rule is probably lacking a rationale. – Lundin Aug 07 '12 at 06:35
-
1If the draft proposal goes through, it looks like this particular rule will be demoted from required to an advisory rule in the next version of MISRA-C. – Lundin Aug 07 '12 at 06:39
-
1@Lundin The question is, do these studies and books say something along "There's a pattern of bugs you can avoid by not using
."? And if so, do they include research that answers "Does not using – Jens Aug 07 '12 at 17:26create other opportunities for other bugs?". MISRA Rules, like anything, are an engineering tradeoff. Maybe some rules actually are making a detrimental tradeoff. -
1@Jens Yes, Les Hatton's book Safer C is basically a scientific report on his population studies on C code. He ran checks on millions of millions of loc and found out what the most common bugs were. Many of the MISRA rules are pretty much copied directly from that book, though some, like this #undef one, are taken out of the blue. – Lundin Aug 07 '12 at 20:49
-
3Anyway, I think the upcoming MISRA standard will prove much better as they have weeded out a lot of rules without a proper rationale, or demoted them to advisory. My own opinion of MISRA is that you should read it with scepticism and make your own coding standard based on it. I have designed such a coding standard for my company, that removed 3-4 weird MISRA rules and added some things not in MISRA, most notably far stricter rules against function-like macros, global variables and other such icky stuff. – Lundin Aug 07 '12 at 20:52
-
1Jens, the original MISRA rules were created by the automotive industry for the automotive industry. They obviously think the cost of adopting MISRA is lower than not adopting MISRA. But I wholeheartedly agree with you about *blindly* following the guidelines... not a clever idea. – Andrew Nov 08 '12 at 07:40
-
You can see the great benefit MISRA has had with the self-driving cars. Heaven forbid, without MISRA, there may be reports of crashes and deaths due to bugs in the self-driving code. Good thing MISRA is there to keep us safe... – David C. Rankin May 25 '23 at 05:21
MISRA has its own explanation on why the usage of #undef
is banned:
#undef should normally not be needed. Its use can lead to confusion with respect to the existence or meaning of a macro when it is used in the code.

- 142,963
- 15
- 272
- 331
-
Requesting you to give an example on this. I can't imagine how it can create confusion ? – bubble Aug 14 '12 at 08:11
-
1@bubble - see my answer http://stackoverflow.com/a/12055764/1614319 as to how confusion can reign – Andrew Nov 08 '12 at 07:36
In reply to @Bubble's comment above:
Requesting you to give an example on this. I can't imagine how it can create confusion ?
Imagine the scenario...
#define MACRO some-definition
.
.
MACRO // Invocation 1
.
.
MACRO // Invocation 2
.
.
And then someone comes along and inserts, between the existing invocations of MACRO
.
.
#undef MACRO
#define MACRO something-else
MACRO // Between (1) and (2)
.
.
The original second invocation of MACRO will not do what you expected!
-
That's a fair point, but could perhaps be resolved by requiring that `#undef` only by used to undefine a macro defined in a particular clearly-defined place. In other words, `#define MACRO ... #undef MACRO` would be allowed, but `#undef MACRO ... #define MACRO` would not. In the former situation, if `MACRO` was unexpectedly defined and used outside that scope, errors would occur when the new macro is defined and when a succeeding attempt is made to use the old one. – supercat Dec 07 '12 at 19:53
-
At the moment, the rule is well defined, and decidable/deterministic... and in most circumstances justified. However, there is nothing to stop the rule being deviated against if a specific circumstance requires it. – Andrew Dec 08 '12 at 07:53
-
-
And @Bubbles asked "Requesting you to give an example on this. I can't imagine how it can create confusion ?" - which I have done. – Andrew Dec 08 '12 at 07:56
-
I've twice encountered situations when programming embedded systems where it was necessary to produce two routines which were almost identical except that they controlled different resources (on both controllers, a statement like `structPtr->Foo += 2;` would be more than three times as big and slow as `someStruct.Foo += 2;`, so duplicating code was less wasteful than a general-purpose routine would have been). I felt the most idiomatic approach was to `#define DRIVE 1`/`#include "drive.i"`/`#undef DRIVE`/`#define DRIVE 2`/`#include "drive.i"`. Then `#drive.i` `#define`d many macros which... – supercat Dec 10 '12 at 15:51
-
..it then `#undef`ed. Neither client imposed a particular coding standard, and such situations too rare to be worth including in a standard like MISRA. Still, it would seem helpful for a standard to indicate how they should be handled (e.g. require that all `#define`s be designated, at the `#define`, as global or temporary, and require that all temporary `#define`s (and only those) be `#undef`ed exactly once, at the end of their logical scope. – supercat Dec 10 '12 at 15:59
-
Just found this. Sorry! #defines have file-scope not any other limited scope, so I'm not sure what you mean by "their logical scope" – Andrew Jul 24 '13 at 13:58
-
Just saw your answer above. The purpose of each `#define` was to define a macro which was used in a particular part of the code. C has no concept of macro scope, but the semantics of the macro meant that it couldn't serve any useful purpose outside a small piece of code; if the same sequence of characters happened to be used later on in the program as an identifier, having the macro definition continue to be effective there would be a BAD THING, best avoided by undefining the macros once they were no longer useful. – supercat Feb 25 '14 at 20:27