2

I'm starting a new C/C++ embedded app and am trying to educate myself about safe coding practices like MISRA, AUTOSAR and my current favorite probably because it's the shortest, NASA's so-called Power of 10 (https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-Critical_Code). I can see the logic behind much of the rules. But all of them try to eliminate or restrict dynamic memory allocation. For example, MISRA C++ rule 18-4-1 says: “Dynamic heap memory allocation shall not be used” and NASA's rule 3 is "Avoid heap memory allocation". AUTOSAR is somewhat less restrictive. I understand their intent is to make sure a system doesn’t run out of memory but I'm not really clear about what a C or C++ compiler allocates as "dynamic heap memory allocation" or "heap memory allocation". I'll edit this post to ask specific questions

  1. Does that mean for example that all variables need to be static? (already answered by @klutt
  2. Just to make sure I understand correctly, are temporary variables defined inside methods declared on the stack and therefore "safe" according to the MISRA, AUTOSAR and NASA guidelines?
  3. "new” can’t be used after initialization according to the AUTOSAR and NASA guidelines?
  4. The C++ library array is OK according to the MISRA, AUTOSAR and NASA guidelines?
  5. But C++ libraries like string and vector can’t be used according to the AUTOSAR and NASA guidelines?
  6. Any other examples of "unsafe" dynamic memory allocation per the guidelines would be appreciated

Thanks - Gene

Gene
  • 47
  • 7
  • No, it does not mean that they should be static. It means that you should not use malloc in C or new in C++. It also means that you should avoid libraries that are using that, so that basically rules out all classes in stl. – klutt Feb 27 '21 at 20:03
  • I edited my post so the questions are very specific and hopefully not opinion based. Hopefully, that will open up the post again. – Gene Feb 27 '21 at 20:18
  • Unsafe - `new` also smart pointers; all of the container classes (except `std::array`); all of the IO classes; you probably need to treat all of `std` and any other library as __potentially__ unsafe until you have check the source code for each class and method. Stubbing `malloc` and breaking on use then inspecting the call stack may also help find unsafe methods. – Richard Critten Feb 27 '21 at 20:44
  • https://stackoverflow.com/questions/48089835/misra-c-rule-18-4-1-and-dynamic-memory-allocation-is-stdstring-permitted – klutt Feb 27 '21 at 21:39
  • Thanks for the input. Can someone explain why my original post was closed? Seems like my original questions were pretty specific regarding MISRA, AUTOSAR and the NASA 10 rules and my edited questions were even more specific. And what will it take to re-open this post? Thanks – Gene Feb 28 '21 at 00:19
  • Why is this tagged `c` . – An Ant Feb 28 '21 at 06:01
  • Rules are not "just for fun", they try to avoid certain problems. The problems with dynamic memory allocation are so many and so difficult to handle that it seems the easiest way to prohibit or at least to limit its use. That is, **_manual_** dynamic memory handling, which is the core of the problem in C and C++. With some thinking, most if not all of your questions can be answered. – the busybee Feb 28 '21 at 09:46
  • Currently I'm working in a SIL4 project (top safety integrity level of CENELEC) and we are not allowed to use any compiler-system provided library, with an extra mention of STL (and exceptions, and extra `enum` checking, and extra array index checking, and...). However, we use `new` during initialization with an own implementation, and implemented `delete` to shutdown the system after an error message. Each copy constructor, copy assignment, and destructor also shuts down the system ("Rule of Three", the compiler to use is C++98). – the busybee Feb 28 '21 at 09:50

2 Answers2

5

At the heart of the MISRA Rule is the problem of dynamic memory allocation

  1. Programmers are inherently lazy, and do not check the return status from malloc() leading to null pointers being used.
  2. The general problem with fragmentation of the heap
  3. The incomplete standard definition of malloc() and its siblings, which is riddled with undefined, unspecified and implementation-defined behaviour which makes portability between compilers and implementations, and hence a level of unpredictability of behaviour.

Some derivatives of MISRA C/C++ (eg JSF, NASA JPL, AUTOSAR) permit the use of malloc() during an initialisation phase (but no realloc() etc or subsequent free()) which removes all of the fragmentation issues - but does not address the incomplete-definitions.

Of course, custom solutions may be perfectly provable, in which case a deviation of the MISRA Rule would be OK.

But in general, the pitfalls in using dynamic memory outweigh any potential benefits.

Disclaimer: Yes, I'm associated with MISRA... see profile

Andrew
  • 2,046
  • 1
  • 24
  • 37
  • This is all excellent input and very helpful. It seems pretty easy to stay away from malloc and the like entirely and only use "new" during initialization. The string, vector and queue libraries seem so useful that it's probably worth the time to understand how to use at least these libraries safely or at least consistent with the AUTOSAR guidelines. That and investing in the time and tooling to do static analysis on a regular basis seems like a reasonable starting place. – Gene Feb 28 '21 at 22:32
  • 3
    Main reasons not to use heap allocation are rather: programs should be deterministic and also since most embedded systems are single-core MCU with bare metal/RTOS rather than running on a hosted OS, [it doesn't make the slightest sense to use heap](https://electronics.stackexchange.com/a/171581/6102). – Lundin Mar 01 '21 at 07:54
  • Agreed @Lundin - but we do have to deal with the **because we can, we can** peeps – Andrew Mar 01 '21 at 21:47
2

Does that mean for example that all variables need to be static?

No, they can be local scope (automatic storage) too. If declared at file scope, they should generally be static (encouraged by MISRA-C and others).

Just to make sure I understand correctly, are temporary variables defined inside methods declared on the stack and therefore "safe" according to the MISRA, AUTOSAR and NASA guidelines?

Yes. Though you need to consider stack overflows, but that's another story.

"new” can’t be used after initialization according to the AUTOSAR and NASA guidelines?

Yes.

The C++ library array is OK according to the MISRA, AUTOSAR and NASA guidelines?

Not at all, there will be restrictions about which parts of the standard library you can use, particularly in MISRA-C++. There's a chapter in the MISRA guidelines stating rules for which headers that shouldn't used. These are pretty lax though, only banning the most crazy stuff like setjmp.h and misc hosted system stuff like signal.h.

For the higher levels of safety-critical systems, you'll eventually require that the standard libs themselves follow MISRA too, when possible. This is rarely ever the case, so mostly you'll try to stay clear of standard libs entirely.

But C++ libraries like string and vector can’t be used according to the AUTOSAR and NASA guidelines?

No they can't. C++ libraries in general are unsuitable for embedded systems. Personally I would never use C++ for anything remotely safety-critical and I have very bad experience from using C++ for embedded projects in general.

You can use it just fine, but it requires a lot from the C++ programmer, essentially you need to be fully aware of what parts that make a safe subset and which ones that doesn't and what assembly every C++ line results in. The average C++ programmer isn't skilled enough to do that, so if C++ is available, they will soon drag in dangerous or bloated features in the project.

In addition, the language has gone further haywire from C++11 and beyond, becoming increasingly unsuitable for embedded systems with more poorly-defined behavior, more rules for type punning and pointer aliasing etc. To document all cases of poorly-defined behavior in C++, you could fill a thick book.

Any other examples of "unsafe" dynamic memory allocation per the guidelines would be appreciated

Mostly it doesn't make any sense to use in embedded systems. If you know how a heap is implemented in a MCU, then common sense is sufficient to see why the heap doesn't fill any purpose. But also since dynamic allocation assumes that some manner of non-deterministic behavior is fine, which is never the case in safety-related software.


Regarding these NASA rules, they are quite shallow and naive. Most of them goes without saying and MISRA-C is far more in-depth. You can dismiss the NASA rules as beginner-level stuff: whoever came up in them as late as in 2006 seemed to have missed out all the research in the 1990s regarding developing safer subsets of C.

The silly rule about "no function pointers" for which NASA never managed a rationale was discussed here: State Machine with no function pointer.

Lundin
  • 195,001
  • 40
  • 254
  • 396