I would like to initialize an array of structs, with the same element repetitively, ie
struct st ar[] = { {1,2}, {1,2}, {1,2} };
However I do NOT want to run any code for that, I wish that the layout of the memory upon program's execution would be like so, without any CPU instructions involved (it would increase boot time on very slow CPU and relatively large arrays).
This makes sense, when using the array as mini ad-hoc database (maps id to struct) and when one wishes to use a default value to all database values.
My best solution was to use something of the form
#define I {1,2}
struct st ar[SIZE_OF_ARRAY] = { I,I,I };
So that the compiler will warn me if I'm having too much or too little I
s. But this is far from ideal.
I think there's no solution for that in ANSI-C, but I thought that maybe there's a macro-abuse, or gcc extension that would do the work. Ideally I would like a standard solution, but even compiler specific ones would suffice.
I thought That I would somehow be able to define a macro recursively so that I(27)
would be resolved to 27 {1,2}
s, but I don't think that's possible. But maybe I'm mistaken, is there any hack for that?
Maybe inline assemby would do the trick? It would be very easy to define such memory layout with MASM or TASM, but I'm not sure it is possible to embed memory layout instructions within C code.
Is there any linker trick that would lure it to initialize memory according to my orders?
PS
I know I can generate automatically C file with some script. Using custom scripts is not desirable. If I'd use a custom script, I'll invent a C-macro REP(count,exp,sep)
and would write a mini-C-preprocessor to replace that with exp sep exp sep ... exp {exp appears count time}
.
The boost preprocessor library (which works fine for C) could help.
#include <boost/preprocessor/repetition/enum.hpp>
#define VALUE(z, n, text) {1,2}
struct st ar[] = {
BOOST_PP_ENUM(27, VALUE, _)
};
#undef VALUE
If you wish to use it, you'll just need the boost/preprocessor
directory from boost - it's entirely self contained.
Although, it does have some arbitrary limits on the number of elements (I think it's 256 repetitions in this case). There is an alternative called chaos which doesn't, but it's experimental and will only work for preprocessors that follow the standard precisely (GCC's does).
The easiest way I can think of is to write a script to generate the initialisers that you can include into your C code:
{1,2},
{1,2},
{1,2}
Then in your source:
struct st ar[] = {
#include "init.inc"
};
You can arrange your Makefile
to generate this automatically if you like.
I'm guessing you can, on the file with the array definition, do:
#include "rep_array_autogen.c"
struct st ar[SIZE_OF_ARRAY] = REPARRAY_DATA;
and have your Makefile generate rep_array_autogen.c
with a format like
#define SIZE_OF_ARRAY 3
#define REPARRAY_DATA {{1, 2}, {1, 2}, {1, 2}, }
Since rep_array_autogen.c
is built on your machine, it would be just as fast as hand-coding it in there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With