How do I create a module in MISRAC:2012 that follows Dir 4.12 and 4.8?
Asked Answered
S

1

5

This question relates to coding in ISO C99 following the MISRAC:2012 guidelines.

I am looking for guidance on Dir 4.8 “If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden” in conjunction with Dir 4.12 “Dynamic memory allocation shall not be used”.

When implementing an Abstract Data Type in C it is common to refer to the ADT using a handle that is a pointer to a structure describing the internal state of the ADT. This can be done using an opaque pointer as per Dir 4.8 with the benefit that the internal details remain hidden from the user.

Generally more than one of these ADTs could exist so there must be a way to create mulitple handles. This can be solved by allocating memory for the internal details referenced by the handle in an initialisation function, however, this is not allowed under Dir 4.12.

Another option is that the initialisation routine receives a pointer to a statically allocated handle provided by the user, however, this cannot be accomplished using opaque pointers.

I illustrate the problem below.

    Module.h 

    struct module; 
    typedef struct module module_t; /* Module handle is only available to  the world as an incomplete type. This allows us to satisfy MISRAC 2012 Dir 4.8.*/

    Module.c

    #include "module.h"
    struct module
    {
        uint8_t value;
    };
    module_t* module_get_a_handle(void)
    {
         return (module_t*)malloc(sizeof(struct module)); /* MISRAC 2012 Dir 4.12 disallows dynamic memory allocation.*/
    }

    User.c

    #include "module.h"
    module_t* module_handle;
    module_handle = module_get_a_handle();

The issue is also described in this question Static allocation of opaque data types , however it is not discussed with respect to the MISRAC:2012 guidelines.

One solution described is to use a statically allocated pool of handles that are made available to client code. This solution seems to be technically compliant; however, it seems that the concept of dynamic memory allocation still exists here. I would argue that although the handles are statically allocated, it cannot be determined by the compiler during compilation whether there will be enough handles available for the software to function correctly.

My solution to this problem would be to write a deviation around Dir 4.8 and use non-opaque pointers and a strong naming convention that makes it clear to users that the internal details of the ADT must not be changed.

I am curious whether there is a well accepted method to solve this issue that satisfies Dir 4.8, and Dir 4.12, and does not break any other MISRAC:2012 rules. Any comments would be greatly appreciated.

Supper answered 11/2, 2016 at 14:23 Comment(0)
F
2

It seems you have understood both the problem and the solution: use a static memory pool from inside each ADT.

This pool needs to be restricted though, to a certain maximum limit, which should be hard-coded. Essentially you will implement the pool as a static buffer at file scope and keep track of the "allocated" size with a counter variable. For each item you add, you check the counter against the max limit.

In case you would run out of space, your program will know it and will be able to handle that error in a safe manner. There should never be a reason why you run out of space though. That would mean that you have a design bug. You should almost certainly be able to ensure that you won't run out of space at compile-time. Or if not, at the very least during code coverage tests.


Directive 4.12 is concerned about dynamic memory allocation on the heap with malloc/free. Using those functions and the heap, is the C de facto standard definition of the term dynamic memory allocation. It does not mean anything else.

There are multiple issues with dynamic allocation: non-deterministic allocation time, segmentation, memory leaks etc etc.

The "dynamicness" in itself is not a concern, as long the program behaviour remains deterministic. Safety standards are always concerned about dynamic memory allocation on the heap, because it implies non-deterministc behavior, which is a cardinal sin in safety-critical software design.

For many common embedded systems such as bare metal/RTOS microcontroller applications, dynamic allocation simply doesn't make any sense at all.


So the static memory pool is not "dynamic memory allocation". Otherwise the use of the stack would too count as "dynamic memory" and it would not be possible to write any useful software at all.

Flavopurpurin answered 11/2, 2016 at 15:0 Comment(2)
The approach outlined here makes sense, but it does not seem possible to follow it when the software is part of a general purpose library. In that case, the knowledge at "file scope" level is limited at compile time.Weariful
@ReinierTorenbeek Alternatively you could pass on an allocator function to the ADT; that way you can centralize the memory pool. https://mcmap.net/q/344156/-static-allocation-of-opaque-data-typesFlavopurpurin

© 2022 - 2024 — McMap. All rights reserved.