9
struct A{
    int a; int b;
};
static const struct A a = {.a1 = 1, .a2 = 42};

struct B{
    struct A[666][510]
};
static const struct B b;

I would like to initialize b with copies of a. However, I cannot touch static const things with memcpy(). And I need b to be static const, because that way it gets put into flash and not ram memory.

How do I make this work. The compiler is arm-none-eabi-gcc with -std=c89, I think.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Vorac
  • 8,726
  • 11
  • 58
  • 101
  • See the answer to http://stackoverflow.com/questions/21528288/c-structure-array-initializing/ – Brave Sir Robin Feb 05 '14 at 11:33
  • 4
    `.a1 = 1` : unknown field. and not c89. – BLUEPIXY Feb 05 '14 at 11:34
  • 1
    Check the linker script for sections that gets put into flash, and add a `section` [attribute](http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes) to place it in that section. – Some programmer dude Feb 05 '14 at 11:35
  • So you want 666*510 copies of the same pair of data? And you want it to be const? I'm just curious how this will be useful. – John Zwinck Feb 05 '14 at 12:15
  • @BLUEPIXY, it's some wierd mix of ansi c and gnu extensions. for example `for(int i = 0;i < 5; i++)` does not compile. – Vorac Feb 05 '14 at 12:45
  • @JohnZwinck, it's default configuration. The module that uses those default values is dumb and wants them all allocated. Plus later we will change them to marginally more meaningful values. – Vorac Feb 05 '14 at 14:19

3 Answers3

1

I recommend that you put these arrays in a separate module in order to achieve encapsulation. Then inside that module you do not need to make B a const but make it static instead. Any access to this data must be done via getters and setters like this:


mydata.h

#define BA_SIZE 666

struct A{
    int a; int b;
};

struct B{
    struct A stuff[BA_SIZE];
};

void init(void);
struct A * getB(unsigned int i);
void setB(unsigned int i, struct A element);

mydata.c:

#include "mydata.h"

static const struct A a = {.a = 1, .b = 42};
static struct B b;

void init(void)
{
    int i;
    for(i=0; i&ltBA_SIZE; i++) {
        b.stuff[i] = a;
    }
} 

struct A * getB(unsigned int i)
{
    return(&b.stuff[i]);
}

void setB(unsigned int i, struct A element)
{
    if (i &gt BA_SIZE) { return; }
    b.stuff[i].a = element.a;
    b.stuff[i].b = element.b;
}


main.c:
#include &ltstdio.h&gt
#include "mydata.h"

int main(void)
{
    init();
    unsigned int num=1;
    struct A * something = getB(num);
    printf("element [%u] a=%i b=%i \n", num, something-&gta, something-&gtb);

    return(0);
}


Tereus Scott
  • 674
  • 1
  • 6
  • 11
  • Making the data `static const` allows the linker to put it into flash, and not the precious ram. And I can do that, as I only need to be reading this data. On the other hand, for changing data, your example looks great. – Vorac Mar 10 '14 at 14:42
1

You can try this, though it works specifically for the dimensions that you specify (666 x 510):

#define X001 {1,42}
#define X002 X001,X001
#define X004 X002,X002
#define X008 X004,X004
#define X016 X008,X008
#define X032 X016,X016
#define X064 X032,X032
#define X128 X064,X064
#define X256 X128,X128

#define Y001 {X256,X128,X064,X032,X016,X008,X004,X002}
#define Y002 Y001,Y001
#define Y004 Y002,Y002
#define Y008 Y004,Y004
#define Y016 Y008,Y008
#define Y032 Y016,Y016
#define Y064 Y032,Y032
#define Y128 Y064,Y064
#define Y256 Y128,Y128
#define Y512 Y256,Y256

static const struct A a = X001;
static const struct B b = {{Y512,Y128,Y016,Y008,Y002}};
barak manos
  • 29,648
  • 10
  • 62
  • 114
  • A little messy, but the way to go. They say macros are the crutches of the language. Thanks a lot! – Vorac Mar 10 '14 at 14:43
0

On linux this complies with gcc -std=c89 (don't know about arm cross compiler)

typedef struct A{
    int a; int b;
} TA;

typedef struct ARR3 {
    TA a[3];
} TARR3;


typedef struct ARR33 {
 TARR3 b[3];
} TARR33;

static const TA a = {.a = 1, .b = 42};

TARR33 aa = {
   .b[0] = { .a[0] = {.a = 1, .b = 1}, .a[1] = {.a = 2, .b = 2}, .a[2] = {.a = 3, .b = 3} },
   .b[1] = { .a[0] = {.a = 4, .b = 4}, .a[1] = {.a = 5, .b = 5}, .a[2] = {.a = 1, .b = 2} },
   .b[2] = { .a[0] = {.a = 1, .b = 1}, .a[1] = {.a = 1, .b = 2}, .a[2] = {.a = 1, .b = 2} }
            };

main()
{
  return 0;
}
MichaelMoser
  • 3,172
  • 1
  • 26
  • 26
  • Well, yea, nut you still need to type all the numbers. In my case the array is much larger than 3x3. It appers that [this](http://stackoverflow.com/a/21530246/1145760) is the only answer. But it is so damn ugly! – Vorac Feb 06 '14 at 08:48