Is there a way (a trick) to init a const array of struct from multiple files with GCC ? I got several "modules" (.c/.h files) that can be build or not. I want each module be able to register itself into a global const array of struct without using RAM (it's an embedded project) .
For instance I got a global dynamically allocated array of pointer to const struct span over several files but I want to remove it from RAM if I can
CodePudding user response:
It's usually not a good idea to initialize something from multiple files, because that in turn suggests that something is weird with the program design. Also to complicate things, C doesn't regard const
qualified variables as compile-time constant expressions, so you can't do const int x = some_other_const;
at file scope.
One dirty old trick to initialize variables from multiple files is otherwise this:
const int array [] =
{
#include "some_data.h"
#include "more_data.h"
};
...
// some_data.h
1,2,3,
// more_data.h
4,5,6,
This is equivalent to:
const int array [] =
{
1,2,3,
4,5,6,
};
For instance I got a global dynamically allocated array
You can't initialize dynamic arrays in compile-time anyway. Also the presence of them in an embedded system project is questionable at best. And in case of bare metal/RTOS it is complete nonsense, see Why should I not use dynamic memory allocation in embedded systems?
Overall it seems that all your problems might originate from a muddy overall program design, so maybe take a step back and review the design before worry about details of the code itself.
CodePudding user response:
One easy way is of course to decide that a module X is included in the build if the corresponding preprocessor symbol WITH_X
is defined. Then you can list them all in the initializer for the struct array:
#include "module_x.h"
#include "module.y.h"
static const struct module *modules[] = {
#if defined WITH_X
&module_x,
#endif
#if defined WITH_Y
&module_y,
#endif
};
where the modules' headers define a public symbol like this, perhaps:
/* In module_x.h */
#include "module.h" /* To get the structure declaration. */
const struct module module_x;
The actual values put in the struct can come from module_x.c
.
I think this should work but the above has not been compiled. I changed to pointers instead of values after @Lundin commented, I toy single-module version built on Ideone at least.