-1

I have typdef'd a struct, and immediately below this I've simultaneously declared and initialised the variables I want using the typedef'd struct.

When I try to compile the code, there are no error messages relating to 'hi_aud', but the rest of the structs bring up the error 'error: ";" expected'. The array also brings up this warning, plus 'error: "}" expected'.

I'm using Hi-Tech C compiler v., which uses the C90 ANSI C standard.

/* Due to C90, do not change order of vars in struct or else code will explode
 */
typedef struct alarm {
    const uint_fast32_t pattern[];
    const uint_fast8_t size;
    void (*toggle)(void);
    void (*off)(void);
    bool on;
    bool init;
    uint_fast8_t pos;
    uint_fast16_t start;
    uint_fast8_t overflows;
};

static struct alarm hi_aud {
    [108, 27, 108, 20, 108, 12, 108, 5],
    sizeof(hi_aud.pattern) / sizeof(*hi_aud.pattern),
    &sounder_toggle,
    &sounder_off,
};

static struct alarm med_aud {
    [255, 50, 50, 255],
    sizeof(med_aud.pattern) / sizeof(*med_aud.pattern),
    &sounder_toggle,
    &sounder_off,
};

static struct alarm lo_aud {
    [255],
    sizeof(lo_aud.pattern) / sizeof(*lo_aud.pattern),
    &sounder_toggle,
    &sounder_off,
};

static struct alarm hi_vis {
    [255],
    sizeof(hi_vis.pattern) / sizeof(*hi_vis.pattern),
    &hi_vis_toggle,
    &hi_vis_off;
};

static struct alarm med_vis {
    [255],
    sizeof(med_vis.pattern) / sizeof(*med_vis.pattern),
    &med_vis_toggle,
    &med_vis_off,
};

static struct *alarms = {&hi_aud, &med_aud, &lo_aud, &hi_vis, &lo_vis};
static uint_fast8_t alarms_siz = sizeof(alarms) / sizeof(*alarms);

edit When I use the '{}' brackets to initialise the array, another error "error: no identifier in declaration" comes up. This does not happen when I use the '[]' brackets.

3 Answers3

3

Inside a strcut's defintion the elements' defintions are separated by ; not be ,. not the issue :}

  • Prior to C99 the initialiser list may not end by ,.confused by C99 change for enums. Ending it with a ; is always wrong. And there needs to be a = between the variable and its initialiser.

  • To initialise a struct's array member use curly braces ({}), not brackets ([]).

  • const uint_fast32_t pattern[]; is not a complete array definition.

    Use const uint_fast32_t pattern[MAX_SOMETHING]; instead.

alk
  • 69,737
  • 10
  • 105
  • 255
  • 2
    This isn't correct, C _always_ allowed initializer lists to end with `,`. From the ANSI C draft: `{ initializer-list }` `{ initializer-list , }`. You are confusing this with trailing comma in enums, which wasn't allowed before C99. The reason it was added was to make enums consistent with arrays. – Lundin Feb 27 '17 at 15:32
  • 1
    The problem is that I forgot to add the '=' between the variable and initialiser. Thanks! – MusicForChameleons Feb 27 '17 at 15:33
  • @Lundin: Yes, correct. Well it's all so dxxm long ago ... :} – alk Feb 27 '17 at 15:51
0

The proper way to initialize an array is with curly-brackets, not square brackets:

static struct alarm hi_aud = {
    {108, 27, 108, 20, 108, 12, 108, 5},              /* Initialize "pattern") */
    sizeof(hi_aud.pattern) / sizeof(*hi_aud.pattern), /* Initialize "size"     */


Assuming you already declared struct alarm properly (and you didn't quite get it, because you missed the second part of the typedef):

Your code is:

static       - This variable will have file-local scope.
struct alarm - The type of the variable.
hi_aud       - The name of the variable
{...}        - The structure initializers

You should also have an = between your variable at the structure initializers.


Addendum:

As others have pointed out, your code is a mess.

  • You did not complete a typedef.
  • You seem to be using variable length arrays in a language which does not support them
  • Your VLAs are in the middle of a structure which has a comment that says the structure may "explode".
  • In initializing structures, you're missing an = sign
  • You are not initializing arrays properly.
  • Your array sizes are all different.
  • You have trailing commas and misplaced semi colons, etc, etc.

In general, Write a TINY amount of code first, compile it, debug it.
Then add on a little bit more, compile it and debug it.
Repeat.

Do NOT write several pages of junk, then look on in wonder as it doesn't work.


Towards that end, lets fix your first typedef:

Typedef works with 2-elements, The TYPE, and the new NAME for the type:

typedef {existing element} {new name};

You only put in the first half.

You want:

typedef struct alarm {  /* All the structure elements */ } alarm_t;

This makes a new type alarm_t.

After that, you tried to make the first element of the structure an array of undefined size. C allows flexible array members, but ONLY as the very last element of a struct, and those are tricky to use. So I'm going to make your array a fixed size:

typedef struct alarm {
    const uint_fast32_t pattern[10];  /* Fixed Size */
    const uint_fast8_t size;
    void (*toggle)(void);
    void (*off)(void);
    bool on;
    bool init;
    uint_fast8_t pos;
    uint_fast16_t start;
    uint_fast8_t overflows;
} alarm_t;
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • In any case, if you're going to close the question as a dupe, then it is inappropriate to also write an answer. – John Bollinger Feb 27 '17 at 15:30
  • Wow, this is a really thorough and in-depth guide. I ended up putting the VLAs in program memory outside of the struct and using a pointer to the array inside the struct. – MusicForChameleons Feb 28 '17 at 08:09
-1

The syntax for typedef for a struct is:

struct <optional struct name> {
    struct fields...
} <typedef name>;

You haven't supplied any typedef name.

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82