I'm required to write the Low-Level Requirements of a Software Component which shall perform signal processing over arrays of 200k elements of integers/floats which lives in the main memory of the program. The program is single thread.
The software shall be certified in the context of DO 178-C (DAL-A).
The signal processing unit will expose functions like these that will be re-used as needed by the rest of the software:
- low_pass_signal_filter
- element_by_element_vector_multiplcation
- ...
We also are based on MISRA-C 2012 to develop in-house Software Code Standard which actually, allows the use of pointers, but pointers to pointers are disallowed.
Rationale about the use of pointers
In the book "Developing Safety Critical Software", by Leanna Rierson she says:
Page 172:
"Recommendation 9: Ensure the software is deterministic. Safety-critical software must be deterministic; therefore, coding practices that could lead to non-determinism must be avoided or carefully controlled (e.g., self-modifying code, dynamic memory allocation/deallocation, dynamic binding, extensive use of pointers, multiple inheritance, or polymorphism). Well-defined languages, proven compilers, limited optimization, and limited complexity also help with determinism."
And also, in page 172:
"1. Minimize the use of pointers. Pointers are one of the most error-prone areas of programming. I cannot even begin to describe the hours I have spent tracking down issues with pointers—always"
Also, in the book "Embedded Software Development for Safety-Critical Systems" by Chris Hobbs, says at page 255:
"At one end of the spectrum, C’s extensive use of pointers, particularly function pointers, makes static analysis very difficult"
Proposal Solution
Furthermore, I've explored so many ideas, and now I'm just exploring the possibility to avoid passing pointers arguments at all to that library, and then just set and fetch data from a dedicated global array.
Here is a simplified example where I have taken the license to condense two files into one single translation unit for simplicity.
Do you think I should continue exploring this way, or rather stick to pointer parameters as usual?
#include <stdio.h>
/* library.c */
#define MAX_SIZE 10
static int g_input [ MAX_SIZE ] = { 0 };
static int g_output [ MAX_SIZE ] = { 0 };
extern void process_input ( const int n )
{
/* process g_input and writes into g_output */
for ( int i = 0; i < ( n < MAX_SIZE ? n : MAX_SIZE ); i = i + 1 )
{
g_output [ i ] = g_input [ i ] * g_input [ i ];
}
}
/* main.c */
#define SRC_SIZE 4
int main ( void )
{
int src [ SRC_SIZE ] = { 0, 1, 2, 3 };
for ( int i = 0; i < (SRC_SIZE < MAX_SIZE ? SRC_SIZE : MAX_SIZE); i = i + 1 )
{
g_input [ i ] = src [ i ];
}
process_input( SRC_SIZE );
int dst [ SRC_SIZE ];
for ( int i = 0; i < (SRC_SIZE < MAX_SIZE ? SRC_SIZE : MAX_SIZE); i = i + 1 )
{
dst [ i ] = g_output [ i ];
}
for ( int i = 0; i < (SRC_SIZE < MAX_SIZE ? SRC_SIZE : MAX_SIZE); i = i + 1 )
{
printf( "%d\n", dst [ i ] );
}
return 0;
}