0

I want to statically initialize an array, but some of its element are pointer to extern struct.

I can't declare the struct as constant, as their element are modified elsewhere, neither static as it clash with extern declaration.

Is there a way to solve this in the static array initialization, or i have to initialize it in a function?

EDIT: looking at your examples after a great launch I just found the error was i was using PWMD2 instead of &PWMD2 (where PWMD2 is the external struct).

Obviously the error was

error: initializer element is not constant

Just to point out what i am doing, the partial of the code (using ChibiOS) is the following:

esc.h

extern struct Engine{
    GPIO_TypeDef *gpio;
    uint8_t pin;

    PWMDriver *driver;
    pwmchannel_t channel;
    pwmcnt_t width;
}engines[];

esc.c

struct Engine engines[] = {
    {GPIOD, 3, &PWMD2, 0, 0},
    {GPIOD, 4, &PWMD2, 1, 0},
    {GPIOD, 6, &PWMD2, 2, 0},
    {GPIOD, 7, &PWMD2, 3, 0},
};
6
  • 2
    What code you have written and what error you are getting? Commented Mar 6, 2015 at 11:44
  • Whenever you get artificial problems like this, it very much sounds like the program design is broken somehow. The real solution to the problem then, is to fix the program design. Commented Mar 6, 2015 at 12:18
  • @Lundin can you please explain your comment? What do you mean by "artificial problems" and how the design is broken? Commented Mar 6, 2015 at 12:35
  • This: "I want to statically initialize an array, but some of its element are pointer to extern struct" sounds like spaghetti coding with various global variables. Either all your variables are constants, and then it is fine, or they are not, in which case the struct should be set in run-time. If I would guess what the program does based on what you have posted, you have an engine driver, which uses PWM and GPIO. In that case, those resources should probably be passed to the driver in run-time. Commented Mar 6, 2015 at 13:35
  • Also, when writing embedded systems it is generally bad practice to rely on pre-initialization of static storage duration variables. You should always initialize them in run-time, manually, before you use the variable. Because there exists nothing but run-time on a true embedded system: you don't want to rely on some copy-down snippet at the start of the program, and you sometimes don't want it at start-up for performance reasons. Most compilers support a non-standard way of omitting the copy-down from .data/.bss, it is usually the default setting even. Commented Mar 6, 2015 at 13:38

2 Answers 2

1

Elaborate on your problem, because the following works ok for me and is what you're asking to do as far as I can tell:

main.c

#include <stdio.h>

#include "externs.h"

static struct_int_t* initextint[1] = { &extint };

int main( int argc, char* argv[] )
{
    printf( "extint: %d\n", initextint[0]->value );
    return 0;
}

externs.h

#ifndef EXTERNS_H
#define EXTERNS_H

typedef struct {
    int value;
    } struct_int_t;

extern struct_int_t extint;

#endif

externs.c

#include "externs.h"

struct_int_t extint = { 10 };

compile:

C:\>gcc main.c externs.c

run:

C:\>a
extint: 10
Sign up to request clarification or add additional context in comments.

Comments

1

The following should work for example. What errors are you getting? What compiler and platform are you on? (You could remove consts as appropriate -- they're not essential.)

struct.h:

typedef struct My_struct {
    int n;
} My_struct;

extern const My_struct s1, s2;

struct.c:

#include "struct.h"

const My_struct s1 = { 1 }, s2 = { 2 };

arr.c:

#include <stdio.h>
#include "struct.h"

static const My_struct *const arr[2] = { &s1, &s2 };

int main(void) {
    printf("arr[0]->n = %d, arr[1]->n = %d\n", arr[0]->n, arr[1]->n);

    return 0;
}

Compile with e.g.

$ gcc arr.c struct.c -o struct_arr

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.