[HN Gopher] MISRA C
       ___________________________________________________________________
        
       MISRA C
        
       Author : skibz
       Score  : 69 points
       Date   : 2023-11-06 04:54 UTC (1 days ago)
        
 (HTM) web link (en.wikipedia.org)
 (TXT) w3m dump (en.wikipedia.org)
        
       | xormapmap wrote:
       | The MISRA guidelines are awful.
        
         | AnimalMuppet wrote:
         | Could you be more specific? Are they badly written, or are they
         | bad at achieving the intended purpose? Or is the purpose itself
         | a bad idea?
         | 
         | And, whichever answer you give to that, _why_ are they bad at
         | it?
        
           | cyberax wrote:
           | They are called "misery C" by people in the industry for a
           | reason. They don't help with the safety all that much, but
           | make a lot of code just fucking ugly.
        
             | GeorgeTirebiter wrote:
             | Exactly. It reduced C to, almost, BASIC. Reduces available
             | design patterns. Reduces available language features.
             | 
             | HOWEVER: having a MISRA-C LINT which is required to run on
             | all code that makes it into an automobile is, ultimately, a
             | good thing. Yes, the homogenization is ugly, but it does
             | mean that classes of errors just can't occur.
             | 
             | The concept is great. There is also MISRA C++ of which I
             | know almost nothing; is that any better?
        
               | gte525u wrote:
               | MISRA C++ lags quite a bit relative to C++'s evolution
               | over the last 20 years. It's closer to JSF C++ style
               | guide.
        
               | bee_rider wrote:
               | I only wrote a little MISRA-C code, but IIRC we had a
               | process to get waivers which was fairly reasonable I
               | think.
               | 
               | BASIC, but with a human-driven process that bumps you
               | back to C when necessary, with the understanding that
               | multiple people look at the evil C-like code, actually
               | seems like a fine language.
        
             | Avshalom wrote:
             | They're called "misery C" because it's an easy joke.
        
       | einpoklum wrote:
       | From my experience, maintaining a standalone/embedded printf
       | library - MISRA is a combination of two things: Common-sense
       | rules, and pain-in-the-ass rules. The former are not very
       | interesting and you probably have them in your head as coding
       | guidelines anyway; but the latter, well, are a pain.
       | 
       | Example: Avoiding implementation-defined types like `int`
       | _every_where, even in places where my code doesn't care about
       | what sizeof(int) is; or when I want to store the result of a
       | system call which returns an int.
       | 
       | I was able to accommodate most (?) of the MISRA rules
       | (https://github.com/eyalroz/printf/issues/77), but mine is just a
       | small library, so I don't know how restrictive they would be for
       | a larger codebase. I suspect it would be painful and force you to
       | avoid some legitimate and useful coding patterns.
        
         | IshKebab wrote:
         | > Avoiding implementation-defined types like `int` _every_where
         | 
         | Well that is the correct thing to do. I guess you can't really
         | complain to MISRA about C being crazy.
        
           | jjnoakes wrote:
           | > Well that is the correct thing to do.
           | 
           | Is it? I can think of quite a few cases where using 'int' is
           | fine; why is that a problem?
        
             | archi42 wrote:
             | Cross-platform code - Is your int still 16 bits on your new
             | CPU? Of course you know* your variable is always between 0
             | and 15, but the MISRA checker might not**.
             | 
             | Today we have int16_t et al., so this is much less of an
             | issue.
             | 
             | *) IME "know" is often merely a "believe".
             | 
             | **) Not sure that even if you have a MISRA checker that has
             | a suitable inference, it is allowed to discard alarms on
             | this kind of violation. I wrote MISRA test cases for
             | something for a suitable powerful checker/analyzer, but I
             | can't remember this detail anymore.
        
               | usrnm wrote:
               | Why do you think that believing that sizeof(int) == 4 is
               | worse than believing that int32_t exists? It doesn't have
               | to
        
               | ska wrote:
               | If I type doesn't exist in your toolchain, your compile
               | will fail an you will know way.
               | 
               | Converstly, incorrect assumptions about size/size/capcity
               | can lead to subtle runtime bugs.
        
             | nicoburns wrote:
             | I can think of lots of cases where carelessly using int
             | might cause issues. And none at all where it's actually
             | better than using a different type. Aside from anything
             | else, it's probably better to default to unsigned types.
             | 
             | I'm fully willing to believe that MISRA-C contains a lot of
             | silly, unnecessary rules, but IMO this isn't one of them.
             | If typing out uint32_t, etc is too long, then you can
             | always create an alias.
        
             | IshKebab wrote:
             | In practice the arbitrary sizing of basic C integer types
             | (int, long, etc.) has proven to be extremely error prone.
             | Basically it's virtually impossible to use them correctly
             | (except in small examples). You don't get any portability
             | benefits because it's too difficult to write code that is
             | _actually_ portable across word sizes, and you get extra
             | bugs when things don 't behave like you expect. There's
             | basically no upside.
             | 
             | It's much less error prone to use fixed size types,
             | especially since approximately all computers are now 32 or
             | 64 bit.
             | 
             | I once lost hours on an Arduino project exactly because of
             | this. I was using the SD card library, and there was an
             | infinite loop bug. Turned out to be because most Arduinos
             | (at the time) are 16 bit, but I was using a 32 bit one. The
             | code had been written using `int` but also assumed that int
             | was 16 bits!
             | 
             | The code was _less_ portable because of the  "portable" int
             | sizing system. It didn't work at all with other sizes,
             | whereas if it had been written using uint16_t it would have
             | worked fine.
             | 
             | You can say "well they made a mistake", but remember we're
             | talking about MISRA. Avoiding mistakes is the whole point.
        
             | ska wrote:
             | > I can think of quite a few cases where using 'int' is
             | fine; why is that a problem?
             | 
             | It's a problem when your toolchain or target changes, and
             | assumptions you were making (explicitly or implicitly)
             | about 'int' now fail in difficult to understand ways.
        
           | AlotOfReading wrote:
           | The relevant MISRA rule (which is advisory, not mandatory)
           | includes avoiding size_t, which is absolutely the correct
           | type to use in a lot of pointer situations.
        
             | MaxBarraclough wrote:
             | Do you have a source for that? From a quick Google it
             | doesn't seem to prohibit size_t.
             | 
             | Rule 3-9-2 (which is only advisory) says _Typedefs that
             | indicate size and signedness should be used in place of the
             | basic numerical types_ , but this doesn't prohibit use of
             | size_t.
             | 
             | https://forum.misra.org.uk/thread-1130.html
        
               | AlotOfReading wrote:
               | I didn't say it prohibited size_t, only that it suggests
               | avoiding it like other variable-sized types. In practice,
               | compliance checkers will turn advisory rules into
               | warnings, which means every usage of a size_t can
               | potentially become a warning message. It's a lot of
               | unnecessary noise for writing correct code.
        
               | IshKebab wrote:
               | Read his link.
        
         | FirmwareBurner wrote:
         | _> you probably have them in your head as coding guidelines
         | anyway_
         | 
         | Ha, if only. Sure, if everyone working on the project is a
         | skilled C dev then yeah, but not when you're piecing together
         | code form a bunch of bodyshops as it often happens in
         | automotive where everything is contracted out to the lowest
         | bidder to push costs down, so MISRA is there as a minimum
         | common denominator to make sure that your code doesn't reach
         | rock bottom in the process.
        
         | gte525u wrote:
         | FWIW - usually when interfacing with foreign code like that you
         | match what the foreign code's types than convert it afterwards.
         | Then add an assert [sizeof(t1) >= sizeof(int)] or better a
         | static_assert.
         | 
         | The intent isn't to make your code bullet-proof. It's to move
         | towards a subset of the language with well-defined semantics.
         | 
         | Any safety critical coding standard work I've done always had a
         | waiver process for both MISRA and mccabe-like complexity
         | requirements - the intent is there's always some point where
         | there is diminish returns for compliance.
        
           | NovemberWhiskey wrote:
           | > _always had a waiver process for ... mccabe-like complexity
           | requirements_
           | 
           | Also known as "the one trick that your test team doesn't want
           | you to know".
        
       | lordfrito wrote:
       | Reminds me of the period in my career I was doing contract work
       | for automotive. I used to work in airbag, highly safety critical
       | real-time stuff, so I knew my way around these kinds of systems.
       | 
       | Mandate came down from customer everything was to be MISRA
       | compliant. Which is great for about 1/2 of your code, just common
       | sense stuff. Like int DebounceVal[NUM_DEBOUNCE_SIGNALS];
       | 
       | For the other half it's essentially impossible, especially when
       | you're writing your own custom tasker/OS (really just a main loop
       | with interrupts) with some simple system calls. The way things
       | were done back then on small 8 and 16-bit systems. You will have
       | serious deviations. There's just no way to disable interrupts
       | without some assembly _somewhere_.
       | 
       | The "non-programmer" types at our customer kept kicking the code
       | back for not being MISRA compliant. So I had to go through a lot
       | of iterations "fixing" things. Led to code that looked like this
       | if (k > ZERO) ...             n = n + ONE;             tens_digit
       | = num % TEN;        hundreds_digit = num % ONE_HUNDRED;
       | 
       | You get the picture.
       | 
       | So code reviews really added no value, because instead of
       | reviewing code (remember these weren't programmers) they just
       | complained about what some automated tool was saying.
       | 
       | After several back and forths I got so sick of things I created a
       | file called MISRA.h to collect all the nonsense defines like
       | this.                  #define ZERO 0        #define ONE  1
       | #define TWO  2        ...        #define ONE_HUNDRED 100
       | 
       | As a joke I put this in the title block                  //
       | MISRAble.h        // (c) copyright blah blah blah
       | 
       | Which of course their eagle eyes caught _that_ , and so the
       | comment itself got flagged by the customer as an open issue.
       | Guess I deserved that one. Funny thing was that they had to track
       | the issue, meeting by meeting, until it was closed out. I think
       | the action item was something like "Remove inappropriate comment
       | from MISRA.h" lol.
       | 
       | As someone else pointed out here... LINT was the _bomb_. Made
       | code so much better. Especially when you could do stuff like this
       | switch (something)           case A                  ...
       | // yes I know I'm falling through to case B
       | //lint -fallthrough           case B:                 ...
       | 
       | Once you got in the habit of appeasing LINT, your code was not
       | only more readable but more explicit.
       | 
       | Good times.
        
         | smaudet wrote:
         | > Once you got in the habit of appeasing LINT, your code was
         | not only more readable but more explicit.
         | 
         | I get the hate, however:                 A) C/C++ sucks at
         | interop.
         | 
         | I don't mean C++01 vs C++13 vs C++15 vs C++17 vs C++19 (and
         | good luck if your project doesn't explicitly specify which type
         | of compiler it needs), I mean Visual Studio vs GCC vs LLVM vs
         | 30 different build flags, compiler versions, target
         | architectures, ABI and caller conventions, linker foibles and
         | just generally one of the most buggy toolchains in existence. A
         | tool like MISRA C doesn't save you from all that exactly, but
         | having a standard at all is important _especially_ when doing
         | security/safety stuff.
         | 
         | In VM (Java/NET/Python/JS) world you have to worry about some
         | library calls and maybe bytecode compatibility, the amount of
         | stuff you don't have to think about is just staggering.
         | 
         | In C/CPP you need to be both disciplined and explicit to safely
         | do just about anything.                 B) Formally provable
         | systems are the dream.
         | 
         | Linter rules do wonders for catching common issues, but they
         | don't catch real bugs very often. The downside of systems like
         | MISRA C etc. is they install a false sense of security "oh it
         | passed the tool so it must be good". In fact you are just _
         | _automating ignoring watching for issues_ _, and worse _
         | _obfuscating the code so finding issues is harder_ _.
         | 
         | But this is why we all hope(d) Rust/Go would save us and
         | produce more reliable software, more cheaply.
        
           | lordfrito wrote:
           | C is a very powerful but very primitive language. Too easy to
           | do all sorts of things you didn't intend.
           | 
           | But C was all we had (we didn't even have C++), and we had to
           | use it, and use it effectively to deliver production firmware
           | that couldn't change after it was shipped. We used it, and we
           | got good at it, and we _loved_ it. And we hated it because we
           | used it and loved it, and that gave us the right to hate it.
           | 
           | Like my above example, when looking at tight (production,
           | performant) C code, you always ask "did the programmer mean
           | to do that?" or "was the programmer aware of the side effect"
           | etc.
           | 
           | Once I groked LINT, I understood that the comments which
           | appeased LINT were also messages to us humans that the
           | programmer had considered the side effects, etc. and that
           | this was intended behavior.
           | 
           | Made it easier to look at other people's code, heck even my
           | old code, because it told me that "yeah, this was
           | considered". Saved a lot of guess work, and allowed me to
           | look at the meat of the code and not be distracted by the
           | simple error stuff.
           | 
           | Also, as much as I love C, my biggest complaint is that it
           | should have been strongly typed from the very start. C# gets
           | this right. You have to be very explicit about mangling
           | things in C#. In straight C it's just too easy to mix types
           | and mess simple stuff up. The compilers attitude is, "sure..
           | I'll compile that". I prefer it asking questions and
           | complaining.
        
         | BeetleB wrote:
         | The problem wasn't MISRA, but your management.
         | 
         | I've worked with the ISO standards for automotive. You can have
         | exceptions to most rules as long as you have a justification
         | that an independent auditor can agree with.
         | 
         | Oh, and the ISO standards don't mandate MISRA. It's just one
         | option.
         | 
         | Also, the rules only apply where safety is relevant. If you can
         | convincingly show that violating some rule won't affect safety,
         | you were good to go.
         | 
         | There are some pretty hefty rules, though. No recursion. No
         | dynamic allocation unless it can't be avoided (and
         | performance/optimization is not a valid excuse).
        
           | lordfrito wrote:
           | > The problem wasn't MISRA, but your management.
           | 
           | Agreed.
           | 
           | But it was my _customers_ management. And the customer is
           | always right yada yada.
           | 
           | So instead of using MISRA to help produce a better
           | deliverable, it gets used as cudgel, a blunt instrument with
           | which to beat programmers with, to create metrics that show
           | the managers are effective at managing.
           | 
           | In these cases, code quality necessarily suffers as a result.
           | Because your resource constrained team has to spend more and
           | more time on busywork.
           | 
           | In my mind, LINT is a better tool than MISRA, because all
           | tools can and will be abused by management, but some tools
           | are more easily abused than others.
        
             | BeetleB wrote:
             | Why did your customer have access to your source code? Or
             | was it the case that they didn't but they could access
             | MISRA reports?
        
               | lordfrito wrote:
               | We were under contract to deliver them a working design,
               | both hardware and software, which they would then
               | manufacture. Basically outsourced R&D.
               | 
               | So software was part of the deliverable. It was their
               | product, their risk, after all.
               | 
               | We didn't do this for long, just to pay the bills until
               | we had our own products that were making us money.
        
           | DaiPlusPlus wrote:
           | > No dynamic allocation unless it can't be avoided (and
           | performance/optimization is not a valid excuse).
           | 
           | Eliminating dynamic allocation is a performance optimisation,
           | I'd have thought?
        
         | glitchc wrote:
         | Such a great story! Thank you for sharing.
        
       | time4tea wrote:
       | a=a; // silence misra unused
       | 
       | Oh the games, oh the kwalitee.
        
         | gte525u wrote:
         | Shouldn't that be (void)a;
        
         | dfox wrote:
         | clang produces explicit warning for that exact statement, while
         | gcc do not.
         | 
         | But well in embedded space there is the another question of how
         | things like IAR behave, which I'm too lazy to test now.
        
       | 0x000xca0xfe wrote:
       | MISRA C is godawful, really bad. It is just a bunch of rules that
       | "sound good" or are good in theory, but I doubt that they
       | actually improve quality at all.
       | 
       | I once worked on a gigantic code base that religiously followed
       | the "no early return" rule. Instead of just returning an error
       | code, everything saved flags and used nested ifs galore.
       | 
       | The code wound along the screen like a dying snake, horizontal
       | scrolling everywhere even with a widescreen monitor.
       | 
       | Refactoring was utterly impossible, fixing simple bugs took
       | months.
       | 
       | I am still baffled how all my colleagues just went along with it
       | and never were like: Wait a second! This is awful!
        
         | ReactiveJelly wrote:
         | Jeez. I proposed to adopt some of the Joint Strike Fighter Air
         | Vehicle rules for C++ [1] at one job, and I went through them
         | marking each as "already in practice", "needs debate" or "I'm
         | vetoing it"
         | 
         | And I vetoed early return with a link to the article on
         | railroad error handling. I don't know how it looks in C, but in
         | C++ and Rust early returns are so much better.
         | 
         | [1] https://www.stroustrup.com/JSF-AV-rules.pdf
        
         | FirmwareBurner wrote:
         | _> I am still baffled how all my colleagues just went along
         | with it and never were like: Wait a second! This is awful!_
         | 
         | They probably went along if MISRA compliance is pushed by a
         | clueless manager who wants to impress a customer with "our 100%
         | MISRA compliance" and who doesn't want to hear about your _'
         | WHYs'_ to exceptions to the rules, then all you can do is
         | blindly comply and suffer through while you look for another
         | job. Ask me how I know.
        
           | staunton wrote:
           | How do you know? (Some anecdotes please?)
        
           | 0x000xca0xfe wrote:
           | Yeah, and this is exactly the problem with standards like
           | MISRA C and the reason I will never work on projects like
           | this ever again.
           | 
           | When rules become more important than reality, everybody
           | directly involved just stops caring.
           | 
           | The early return rule is easy to check, but what about a
           | "don't write code with a mental load so high that nobody will
           | be able to understand it next year" rule?
           | 
           | If the customer wanted actual quality, they would hire
           | dedicated testers and/or write a really good testing harness.
        
             | FirmwareBurner wrote:
             | _> Yeah, and this is exactly the problem with standards
             | like MISRA C and the reason I will never work on projects
             | like this ever again. _
             | 
             | I think it's unfair to point the problem as being with
             | MISRA. MISRA doesn't force you to be 100% compliant with
             | everything there, you're free to pick and choose what you
             | think makes sense for your project and use case and to have
             | your own exception. It's just a set of guidelines, that's
             | it..
             | 
             | The real problem is people(mangers) who don't understand it
             | and want 100% compliance at all cost just because it sounds
             | good and they feel it covers their ass ( _" nobody ever got
             | fired for being 100% MISRA compliant"_ /s), instead of
             | investing dev brainstorming time in pruning the list and
             | having a sane review and approval process for exceptions.
             | 
             | It's a problem with moving from engineering mentality to
             | bodyshop mentality.
        
               | bluGill wrote:
               | 100% is easy to measure and report on. As soon as you
               | allow even one exception it is really hard to figure out
               | if the exception is really needed, or it is just a bad
               | programmer being lazy at the expense of quality.
               | Management should not have to figure that question out.
        
               | FirmwareBurner wrote:
               | _> it is really hard to figure out if the exception is
               | really needed, or it is just a bad programmer being lazy
               | at the expense of quality_
               | 
               | That's exactly why you have (in self respecting
               | companies) a sane internal standard for exceptions with
               | workshops and trainings, and experienced senior devs
               | review the exception requests, precisely to make sure
               | it's never a lazy dev or junior.
        
             | actionfromafar wrote:
             | I guess the implied reason is something like "don't make
             | functions which can accidentally leak resources". "It would
             | probably help to ban early returns."
             | 
             | NO. It won't help. At all.
        
         | jpfr wrote:
         | The recent 2023 version of MISRA C costs just a few pound as
         | PDF. So I got it from $WORK. I don't have a lot of experience
         | with the previous versions. But the 2023 version reads quite
         | okay.
         | 
         | It is not possible to mandate "though shall write good code"
         | because it is not at all clear what that means. Instead they
         | needed to come up with rules that can be checked with automated
         | tools.
         | 
         | The rules are classified as mandatory, required or advisory.
         | Only the mandatory rules cannot be overridden by explicit
         | documentation. As an example, "The goto statement SHOULD not be
         | used" is an advisory rule. Given the bad bad spaghetti code
         | that beginner programmers produce with goto, this is quite
         | reasonable. Even though some code is definitely better _with_
         | goto. For example to jump to some cleanup before returning.
         | 
         | Similarly, "A function SHOULD have a single point of exit at
         | the end" is an advisory rule only. The rationale for the rule
         | stated in the standard is the following (slightly rephrased):
         | 
         | 1. A single point of exit for a function is required by the IEC
         | 61508 and ISO 26262 standards as part of the requirements for a
         | modular approach. 2. Early returns may lead to the
         | unintentional omission of function termination code. 3. If a
         | function has exit points interspersed with statements that
         | produce persistent side effects, it is not easy to determine
         | which side effects will occur when the function is executed.
         | 
         | I'm also a big advocate for early return. But the points from
         | the rationale are valid. And I don't have a good alternative
         | rule that achieves the same goal and is checkable with
         | automated tools...
        
           | 0x000xca0xfe wrote:
           | That's the thing. The rationale sounds good. But where is the
           | evidence?
           | 
           | The code base followed all the rules, yet it was worse and
           | had more bugs than any non-conformant code base I have ever
           | seen.
           | 
           | And teaching beginners to strictly follow rules instead of
           | mercilessly rewriting and testing code until it is
           | sufficiently clean and correct is the worst you can do, IMHO.
        
           | DaiPlusPlus wrote:
           | > Even though some code is definitely better with goto. For
           | example to jump to some cleanup before returning.
           | 
           | I'd have thought by-now that they'd be mandating dialects of
           | C with try/finally instead of goto for error-handling.
        
         | actionfromafar wrote:
         | That's the rule that stuck with me. Because I hate it.
        
         | bluGill wrote:
         | No early return is critical to understanding and maintaining
         | functions of more than 10,000 lines. (probably the limit is
         | around 100 lines, but in my experience functions are either
         | less than 100 lines, or more than 10,000 lines - you rarely see
         | anything in the middle in the real world). I'm a firm believer
         | in not writing long functions so I like early return, but
         | having had to deal with 60,000 line functions early return
         | makes it even harder to figure out how to get someplace or why
         | you didn't.
        
         | zik wrote:
         | I honestly think that MISRA ends up creating worse code that's
         | less reliable because it forces programmers into contortions to
         | get even simple stuff done. It's like programming with one hand
         | tied behind your back - and a lot of it seems to be for no good
         | reason.
         | 
         | I'm thoroughly convinced that MISRA was invented by someone who
         | hates programmers and just wants to see them suffer for no
         | reason.
         | 
         | Can't use size_t because it's a variable sized type? Yeah,
         | that's not a win.
         | 
         | Can't do early returns to keep code clean and clear? Now we
         | have to do a heap of flags and nesting, resulting in less
         | maintainable code. I'm so grateful to have my code improved
         | this way.
         | 
         | Even the experts say that "deviations" are sensible and
         | necessary. So what that really means is you shouldn't ever
         | fully comply with MISRA because it's against common sense. And
         | what does that tell you about companies which require MISRA
         | compliance?
        
       | enriquto wrote:
       | Together with the JPL coding standards [0], and the linux kernel
       | coding style [1], this determines a pleasant, safe and sane
       | subset of C. (Note: this does not mean that these rules should be
       | followed blindly in all cases; but one should be familiar with
       | them and understand their purpose before breaking them.)
       | 
       | [0]
       | https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Dev...
       | 
       | [1]https://github.com/torvalds/linux/blob/79c70c304b0b443429b2a..
       | .
        
         | FirmwareBurner wrote:
         | Might I suggest better alternatives as more pleasant
         | alternatives to the stuffy MISRA C book:
         | 
         | - _" Embedded C Coding Standard"_ by Michael Barr [1], CTO and
         | co-founder of Barr Group, the guy who inspected the ECU code
         | and testified in Toyota's unintended acceleration lawsuit [2].
         | Good stuff.
         | 
         | - _" Embedded System development Coding Reference guide"_
         | written by the Software Reliability Enhancement Center of Japan
         | [3], which covers and expands on MISRA C and more. It's a joy
         | in examples, explanations and eye-pleasing aesthetic. I love
         | it.
         | 
         | [1]
         | https://barrgroup.com/sites/default/files/barr_c_coding_stan...
         | 
         | [2]
         | https://www.safetyresearch.net/Library/BarrSlides_FINAL_SCRU...
         | 
         | [3] https://www.ipa.go.jp/publish/qv6pgp00000011mh-
         | att/000065271...
        
         | ndesaulniers wrote:
         | Linux kernel doesn't use a subset; it uses a superset of nearly
         | every GNU C extension. Linux could only be compiled with GCC
         | for so long due to its excessive use of GNU C extensions which
         | tightly bound the codebase to one tool chain. (We fixed this in
         | clang by implementing most GNU C extensions, at least the good
         | ones).
         | 
         | VLAs are banned, those are c99.
        
         | smcl wrote:
         | I'm sorry, but you've clearly just skimmed this and haven't
         | worked with, nor understood, the purpose of MISRA C. For
         | starters, unless it's changed substantially since I worked with
         | it, MISRA C forbids use of functions like _malloc_ which rules
         | it out for an enormous number of applications. Plus it 's a
         | little bit fuzzy in how some of the rules should be
         | interpreted. Like there was one where it says there shouldn't
         | be commented-out fragments of code (our response was to try to
         | parse the lines of each comment, if they succeeded raise a
         | MISRA-specific compile error). There were a few more weird
         | things with MISRA C, but these were a couple that stuck with
         | me.
         | 
         | It's not a "sane" subset of C you can just pick up and run
         | with. It's a narrow subset of C for a very specific use case.
        
       | MichaelNolan wrote:
       | How common is mutation testing in safely critical applications? I
       | wonder if requiring a high mutation testing coverage would be
       | more effective than adhering to misra C. (Though this seems like
       | a ?Por Que No Los Dos? situation)
       | 
       | https://en.m.wikipedia.org/wiki/Mutation_testing
       | https://pitest.org/quickstart/mutators/
        
         | gte525u wrote:
         | Safety critical in aerospace uses MCDC as the gold standard for
         | testing.
        
           | FirmwareBurner wrote:
           | MCDC is also required in automotive for the highest safety
           | critical components (steering, powertrain, etc)
        
       | maldev wrote:
       | Really sad to see so many people rail on this.
       | 
       | Here's all the examples I've seen shitting on it and why MISRA is
       | correct despite their objections.
       | 
       | 1. ""no early return" rule" In C, you have to be really careful
       | with your flow control and memory allocations. So basically ALL
       | good C programmers and styles dictate that you use GOTO's for one
       | location, a "cleanup" location, in which you check and free
       | memory. So if you do
       | 
       | if(!ptr) return;
       | 
       | You do
       | 
       | if(!ptr) { DEBUGLOG("Error allocation ptr");//Also prints out
       | file, line, function etc. bRet = FALSE; goto cleanup; }
       | 
       | Very common, and you can't ever mess up freeing memory. This is
       | why it's used.
       | 
       | 2. No magic numbers.
       | 
       | Another person complains about not being able to do magic
       | numbers. While it can get tedious, you really shouldn't. They use
       | the most insane example of #define ONE 1. BUT, even in this case
       | you can argue that if the requirements were changed for a base 8
       | or other numbers system, you could easily port the app by just
       | changing these define macro's rather than scouring through the
       | code. It's not that tedious, and it can make the codebase more
       | flexible and solve issues and porting.
       | 
       | 3. Not able to use 'int'
       | 
       | You should always be explicit with your types. Even rust mainly
       | makes you use sized variables. Why just do int, be specific, you
       | may want int32. The C standard is pretty flexible with things
       | like "long" just being bigger or the same size than "int". So
       | porting things like this makes it robust. You also have the fact
       | that if you do any networking or messages of any kind, this makes
       | the datastructures easily portable since you know exactly what
       | size.
        
         | almostnormal wrote:
         | > Very common, and you can't ever mess up freeing memory.
         | 
         | Except that where misra is applied, there often is no dynamic
         | allocation at all.
        
           | RealityVoid wrote:
           | Most of the times, not always. They sometimes don't use
           | malloc or free but their own special little memory pools.
        
             | BeetleB wrote:
             | From my experience in automotive, the ISO standard is
             | against dynamic allocation if your system is classified
             | high enough in terms of their safety levels.
             | 
             | As an example, we weren't allowed to use the C++ string
             | class, and had to find a "safer" string class for C++.
             | 
             | (Not sure about MISRA - most of my experience is with the
             | ISO standard, and MISRA is not mandated by it).
        
               | RealityVoid wrote:
               | Yeah, so what they do is they don't use free and malloc,
               | but use a bunch of buffers they free. Tadaa! We don't
               | have dynamic allocation, just buffers, see? I've seen it,
               | I can count in AUTOSAR systems like... 20 different hand
               | spun allocators, 10 ques and 50 special little
               | hierarchical state machines.
        
               | DaiPlusPlus wrote:
               | Forgive my lack of exposure to safety-critical C, but
               | without dynamic allocation how does a program handle
               | large state with indeterminate lifetimes? Or when you
               | need a temporary buffer that's too big to live on the
               | stack?
        
               | RealityVoid wrote:
               | You make the stack bigger. You might think I'm joking,
               | but I'm not.
               | 
               | Or you make it static. You can work around it just fine.
        
               | BeetleB wrote:
               | > but without dynamic allocation how does a program
               | handle large state with indeterminate lifetimes?
               | 
               | If you haven't, I strongly encourage taking a
               | workshop/course on requirements engineering (not specific
               | to SW nor safety). One thing that stood out is a
               | requirement that says things like "indeterminate" or
               | "large" are red flags. A requirement should state bounds
               | on what sizes it should handle.
               | 
               | > Or when you need a temporary buffer that's too big to
               | live on the stack?
               | 
               | Do you have an example of where this may occur in a
               | safety critical system?
               | 
               | I've forgotten the details, but many/most forbidden
               | things are allowed in the code provided you have
               | watchdogs for mitigation - so if things did fail it could
               | safely shut down. I don't recall if dynamic allocation
               | fell into that category.
        
         | RealityVoid wrote:
         | MISRA is sometimes unfairly shat on, sure, but some things do
         | require you to use your brain.
         | 
         | Regarding magic numbers, if my memory is not playing tricks on
         | me, MISRA does not include 0 or 1 as magic numbers. Regardless,
         | 1 is 1 regardless the number system you work in, I have never
         | ever seen someone "yes, let's make 1 not be 1" (not in a sane
         | way at least) and defining stuff like that for "improved
         | flexibility" is an antipattern in my book. It makes code
         | bigger, harder to navigate and understand. That kind of code
         | does unexpected stuff, is hard to work with and has more bugs.
         | The less surprises, the less indirection I get in a code base,
         | the better. I also feel it makes refactoring harder not easier.
         | I speak from experience, I've worked with codebases like that,
         | they suck. (Hello Vector, if anyone working for them is out
         | there!)
        
         | bluGill wrote:
         | #define ONE 1 is bad code.
         | 
         | good code would be #define MAX_FOO 1 #define
         | TOTAL_SUPPORTED_BAR_COUNT 1 #define STATUS_BYTE_OFFSET 1
         | 
         | The important thing there is even though all are one we have
         | both given them a unique name, and indicated why they are one.
        
         | lordfrito wrote:
         | > 2. No magic numbers. > > Another person complains about not
         | being able to do magic numbers. While it can get tedious, you
         | really shouldn't. They use the most insane example of #define
         | ONE 1. BUT, even in this case you can argue that if the
         | requirements were changed for a base 8 or other numbers system,
         | you could easily port the app by just changing these define
         | macro's rather than scouring through the code. It's not that
         | tedious, and it can make the codebase more flexible and solve
         | issues and porting.
         | 
         | I agree with you on magic numbers in general, but there have to
         | be practical limits.
         | 
         | I was paid to deliver tight production code that was
         | performant, often interfacing with assembly because that was
         | what we had to do with the cheap micro our project used. I
         | wasn't worried about other number systems, it wasn't worth
         | spending R&D $$$ to make the code compatible with other number
         | systems. I'm not writing code that will last 100 years. I
         | deliver to schedules and budgets. Your arguments strike me as a
         | bit too rigid, too academic. Not practical in the real world.
         | 
         | In my mind                  if (condition)          num_found =
         | num_found + 1
         | 
         | is clearly superior than this MISRA version                  if
         | (condition)          num_found = num_found + ONE
         | 
         | Because the first case is the simplest implementation,
         | incredibly explicit as it. We're counting something. That's
         | abundantly clear.
         | 
         | The second case is inferior because, as a reviewer doing their
         | job, I have to go and lookup what ONE actually _is_. In case
         | someone defined it weird. I start thinking  "Maybe it's not 1,
         | maybe it's 1.0". or "maybe its fixed point like (1.0 * 256)."
         | 
         | The moment I'm wondering what ONE is actually defined as, I'm
         | no longer thinking about the code I'm reviewing. I have to
         | interrupt my mental process to go find ONE, understand _that_ ,
         | and then come back and pick up with what I was reviewing.
         | 
         | This stuff matters. Clarity matters. When 1 might not be 1,
         | well then I have to think harder. Compounded, all these little
         | complications dilutes the quality of the code overall. And
         | programmer resources and time are limited.
         | 
         | Also, not to nitpick but your example "goto cleanup" is also
         | not MISRA compliant. I'd argue that use of gotos is a greater
         | sin than returning early.
         | 
         | I'm pragmatic. I've used gotos, where it makes sense, which is
         | almost never. But never say never. Gotos are _nearly always_
         | bad. Early returns are useful _sometimes_. Assembly should be
         | avoided _when possible_.
         | 
         | Code is a tradeoff. When writing interrupt service routines,
         | performance matters, and I found this is where I broke the
         | MISRA rules the most. Because the code _had_ to be tight. That
         | was the value my company brought to the customer. We could get
         | out of the interrupt quick enough to guarantee deadlines in the
         | rest of the code. You do this by letting yourself write complex
         | code in some places, the places that matter. And you scrutinize
         | those more than you do the rest of the code.
         | 
         | MISRA (as misapplied by mid level managers) pretends the above
         | statement doesn't matter.
        
         | Krssst wrote:
         | > In C, you have to be really careful with your flow control
         | and memory allocations
         | 
         | I was going to ask if an early return could still be called
         | "early" if there were resources to free, but I would say error
         | checking after locking an object would still qualify (releasing
         | the lock being necessary).
         | 
         | C++ helps with this with RAII.
        
       | ribs wrote:
       | MISRA is there as a standard for safety-critical code. Some
       | contracts, some customers, some regulatory regimes will require
       | compliance with MISRA, or perhaps another embedded coding
       | standard, like AUTOSAR.
       | 
       | Generally, your customer/regulator will allow you to deviate from
       | the standard; you just need to document and explain the
       | deviations.
       | 
       | A static analysis tool like Helix QAC or Klocwork (bias: my
       | company Perforce sells them) will capture your compilation and
       | scan your code in detail to find deviations from the standard.
       | You can then fix those deviations, or use the tool to document
       | and explain them.
        
       | dfox wrote:
       | MISRA C is total nonsense. If you need that then you should not
       | be using C. Either you can just write the thing in straight
       | assembler while observing the same set of rules and the result
       | will be more readable (or well, COBOL which is more or less an
       | equivalent to C with MISRA C rules) or you should use some high
       | level language intended for that kind of application where the
       | compiler can check for the issues that this ruleset tries to
       | handle, which means Ada (or another application-specific weird
       | Pascal/Modula dialect like CHILL or whatever).
        
       ___________________________________________________________________
       (page generated 2023-11-07 23:01 UTC)