4

Our company are now ISO-13485 (Medical devices) and wants to use MISRAC2012. I read the standard, but I cannot figure out whether or not I am allowed to disable some rules if I think it could improve both stability and readability.

Two examples:

MISRA only allows 1 return statement per function. This often lead to nested conditional structures that look like Christmas tree. I really don't think this rule increase safeness because it makes the code less readable and more error prone.

MISRA only accept functions that have a prototype, even for static ones. This allows the programmer to place his functions anywhere in the file without respect of the calling order. Without prototype the main function has to be the latest function in the file and multi-function recursion is not possible because a function can only call the one declared above itself.

If I want to disable these two rules, can I do it? Would any customer blame me for this?

Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
nowox
  • 25,978
  • 39
  • 143
  • 293

3 Answers3

5

MISRA-C:2012 has 3 categories that all directives and rules sort under:

  • Mandatory. You must follow these and you are not allowed to make deviations.
  • Required. You must follow these, but you are allowed to break them if you raise a formal deviation from the rule. You need a good reason why.
  • Advisory. It is recommended to follow these, but you can break them without raising a formal deviation (although raising a deviation is recommended practice).

The idea behind deviations is that your company should have a routine to deal with them, such as an internal quality errand or something to bring up during code review meetings etc. The idea is that someone else except yourself must be involved in the process of creating a deviation, preferably someone with extensive C knowledge. This is described in MISRA-C 5.4 and there's also an additional guidance document called MISRA Compliance:2016 that might be helpful.

My personal advise for how to implement deviations, is to not allow them at all on case-by-case basis. Instead, a separate coding standard document for the company should be established - you need some manner of document to claim MISRA compliance anyway. This document should contain a list of all company-wide deviations. If there is a need to deviate, the company-wide document must be updated. This actually saves you from implementing a lot of bureaucracy routines and it saves you from various less experienced programmers coming up with weird ideas, just because they don't understand the MISRA-C rationale for the rule.


As for the one return statement per function, it is in my opinion a known defect in MISRA-C inherited from IEC 61508 (I think I'm the only one who actually bothered researching where the requirement comes from). You should raise a permanent deviation against the rule, since it is nonsense. Personally I rephrased the requirement as "functions should not have more than one return statement, unless several return statements leads to more readable code". This covers what was hopefully the true intention of the rule, namely to avoid spaghetti programming.


MISRA only accept functions that have a prototype, even for static ones. This allows the programmer to place his functions anywhere in the file without respect of the calling order. Without prototype the main function has to be the latest function in the file and multi-function recursion is not possible because a function can only call the one declared above itself.

I don't believe this makes any sense, seems like you are trying to solve a problem which doesn't exist. You should avoid accidental recursion by 1) actually knowing what you are doing and 2) use static analysis tools, as required by MISRA.

If you want the call stack to be func1() -> func2() -> func3() and block func2() or func3() from calling func1(), that is best solved with proper program design. Giving the functions intuitive names and using common sense will get you very far.

If that's not enough, then you can split your translation unit in two and create a separate h/c file pair for the internals. The risk you describe is mostly a problem if you have very long source files with a lot of functions in them, to the point where the programmer is losing track of them. That too is a good indication that the file (and/or the functions) should be split in several.

As for the rationale behind this MISRA rule, it is a very sound one, namely to block old C90 crap from "inventing" a calling convention (implicit int return type, making up parameters etc), just because the compiler can't find a function prototype. You definitely should not deviate from this rule.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Oh btw, the rule actually says all functions must have a _prototype_, and not that all functions must have a forward declaration! These are different things. See: https://stackoverflow.com/a/43783993/584518 – Lundin Oct 05 '17 at 06:59
  • Could you, perhaps, stick the prototype of the function immediately before its actual implementation? I've not read the rules, but would seem to satisfy "_MISRA only accept functions that have a prototype_" while still not letting you (or at least warning you, depending on compiler settings) should you try to "forward call" a function? – TripeHound Oct 05 '17 at 07:51
  • Thanks for this wonderful answer. About the prototypes I created a separated question [here](https://stackoverflow.com/questions/46580644/why-function-prototypes-are-they-required-in-misra2012) – nowox Oct 05 '17 at 07:59
  • 1
    Nice answer! And you are not alone who actually checked the IEC 61508. I also did and came to the opinion that it was meant for languages like Assembly or BASIC where you can enter and exit a function just about anywhere. – Melebius Oct 05 '17 at 10:34
  • @Melebius IEC 61508:7 C.2.9 says (among other things) "subprograms should have a single entry and a single exit only". No rationale is provided. One single reference: Structured Design - Fundamentals of a Discipline of Computer Program and Systems Design. E. Yourdon, L.L. Constantine, 1979, ISBN 0-13-854471-9. [Amazon link](https://www.amazon.com/Structured-Design-Fundamentals-Discipline-Computer/dp/0138544719/ref=sr_1_1?ie=UTF8&qid=1507207757&sr=8-1&keywords=Structured+Design%3A+Fundamentals+of+a+Discipline+of+Computer+Program+and+Systems+Design.). – Lundin Oct 05 '17 at 12:49
  • Needless to say, this old crap is mostly irrelevant in a modern program design discussion in the year 2017. Overall, IEC 61508 is filled with very questionable sources. (Such as "Weekly newsletter from TUF, written in german". Not kidding.) And this is the standard engineers use for designing safety-critical industrial systems... – Lundin Oct 05 '17 at 12:50
  • You get a +1 for being able to cite 61508 as the origin of the Guideline – Andrew Oct 13 '17 at 13:14
  • @Andrew Not that hard since it is mentioned in both source and rationale for the rule :) In MISRA-C:2004 the only thing we got as "rationale" was: _This is required by IEC 61508, under good programming style_. Which triggered me quite a bit back then. And then when you check where 61508 got this from, it's from some dinosaur programming book from 1978. I have pointed out several times to the MISRA committee that this is not a valid source, notably during the review before MISRA-C:2012 release. MISRA-C is not the only standard which has inherited the defect though, ISO 13849-1 got it too. – Lundin Oct 13 '17 at 13:22
  • I know, Lundin, but it is amazing how selective people's reading can be :-) This topic is constantly under review... as with *goto* which has been relaxed. – Andrew Oct 16 '17 at 10:11
  • @Andrew ...which was a mistake too. While is perfectly possible to use goto in clean and readable ways, it is at the same time possible to write the very same code without goto, in even more readable ways: instead of "on error goto", use function returns. That is: goto is a 100% superfluous language feature. There would be no harm in banning it, as in MISRA-C2. As a side-effect, the "goto considered harmful" debate would be banned from MISRA code reviews, which is always nice. – Lundin Oct 16 '17 at 10:47
  • Wow, why not just point to the sections in the standard, rather than these long-winded opinionated answers? This is what gives MISRA a bad name. Yes, there would be great harm in "banning [goto] it." "Banning" is a stupid word, leaves little respect for the code review (and the deviation process) which is the real point - not to mention there are very good reasons when they (gotos) are justified. If you don't believe me, then try spending some time in code reviews and picking your battles... – Veriloud Nov 26 '17 at 04:04
  • @Veriloud Regarding option-based answers: looking at your own answer, it completely lacks references (unlike mine) and consists of 100% opinions. The only part of this answer (comments are not part of the answer on SO) that is opinion-based, is that I point out that the rule about one single return statement, is in fact opinion-based. MISRA inherited it from IEC 61508 that inherited it from an ancient programming book from 1979. If it is opinion-based to point out that safety-critical systems in the year 2017 should not be designed based on outdated programming books from 1979, then so be it. – Lundin Nov 27 '17 at 07:54
  • @Veriloud Regarding goto: it is widely recognized that the _only_ valid use of goto is "on error goto" constructs - non-conditional jumps downwards for error handling purposes. But rather than using "on error goto" patterns, experienced programmers tend to use `type wrapper (void) { init(); type result = func(); clear(); return result; }`, where `func` is a function that returns upon error. Upon demonstrating this to programmers during code review, they almost always stop using goto. It is a 100% superfluous language feature that only creates pointless conflict. – Lundin Nov 27 '17 at 08:03
  • @Lundin, AFA “single returns”, you say deviations should not be done "at all on case-by-case basis”, and then suggest rephrasing to "unless several return statements lead to more readable code”. When/how/what determines “readable code”? Your opinions imply deviations are not a solution, but an onerous formal process. The whole idea behind a precise rule is for automatic code review for the sake of efficient manual review, which is by definition case-by-case. Before you say I’m in la-la land (I happened to be so, on vacation), yes, I understand the realities of certain bureaucracies. – Veriloud Dec 04 '17 at 22:50
  • @Lundin, AFA the old “goto debate”, no, not going there, but I see another reason why you don’t like the “single return” rule” ;-) I'm assuming a deviation mechanism which is also highly automated and tightly integrated with good static analysis/source control/code review tools. This also makes automatic code review on complexity metric thresholds as a check for spaghetti (and “readable code”) more manageable. Good tools should also deal with exceptions easily so they won’t screw with your wrapper idea ;-). – Veriloud Dec 04 '17 at 22:50
2

Rule 15.5 (A function should have a single point of exit at the end) is a Advisory rule. So, should your in-house processes so document, you can disapply this Rule.

Rule 8.2 (Functions shall be in prototype form) is a Required Rule, for (IMHO) sound reason - in that it ensures that you explicitly define the function return type and number and types of all parameters, thus avoiding undefined behaviour.

Should you so desire, you can Deviate the Guideline, but this requires you to justify that decision!

Andrew
  • 2,046
  • 1
  • 24
  • 37
1

You can follow the deviation process, and part of that process is the deviations are reviewed by qualified technical personnel. Deviations can cover individual instances of non-compliancy and can also be project-wide.

So how would you justify the project-wide deviations that you are asking for?

I would argue at best, each individual violation should be reviewed. In some cases your reasoning, for example, deep nesting can be unreadable/unmaintainable, must be weighed by the question why are they so deep in the first place? In other words, maybe the function is doing too much and needs to be broken into smaller modules.
I'm assuming you're using a static analysis tool that's smart enough to provide a means to not keep reporting a violation once the deviation has been approved.

Veriloud
  • 417
  • 3
  • 9
  • Personally, I believe that project-wide deviations should not be allowed, but rather all deviations should be _company-wide_, as in "this is how we write safe C". In my experience, the MISRA rules fall into three categories: "always makes sense", "never makes sense" and "makes sense except in some cases". All of these can be figured out in advance. For example the requirement to follow ISO C must always be deviated from in embedded systems, because you will always need inline assembler and interrupts. Allowed exceptions from the rule can be listed in documentation of the deviation. – Lundin Oct 04 '17 at 14:11
  • I agree with your "Company Wide" idea - and (personally) enshrine many such "Deviations" (especially relating to the Advisory Rules, but also wrt those you cite) in the Company coding standards. What is important is that Deviation or Dis-application is approved at an appropriate level. As an aside, I'm happy to discuss those you consider "never makes sense" :-) – Andrew Oct 16 '17 at 10:20
  • Not all companies develop the same levels of safety-critical software, so no, I disagree. – Veriloud Nov 26 '17 at 03:57