1

In trying to solve this problem, I've been copying the example given in this question How do you make an array of structs in C? So now my code looks like this:

#define NUM_TRACES 6

typedef struct 
{
    uint32_t upstream_pin;
    uint32_t dnstream_pin;
    uint32_t led_pin;
}trace;

struct trace traces[NUM_TRACES];

traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0};
traces[1] = {GPIO_Pin_4, GPIO_Pin_6 , GPIO_Pin_1};

But I get the following errors

src/hal.c:17:14: error: array type has incomplete element type
 struct trace traces[NUM_TRACES];
              ^
src/hal.c:19:1: warning: data definition has no type or storage class
 traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0};

I can sort of fix the first error by making the array be an array of pointers to trace structs which I think makes sense

struct trace* traces[NUM_TRACES];

but then these lines give an error

src/hal.c:19:1: warning: data definition has no type or storage class
 traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0};
 ^
src/hal.c:19:1: warning: type defaults to 'int' in declaration of 'traces'
src/hal.c:19:1: error: conflicting types for 'traces'
src/hal.c:17:15: note: previous declaration of 'traces' was here
 struct trace* traces[NUM_TRACES];
               ^
src/hal.c:19:1: warning: excess elements in array initializer
 traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0};
 ^

Which I think is caused by trace[0] actually being a place to store the address of the data, not a place to store the data? But I don't know how to correct this and place the data where I want it in array.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Indigo
  • 962
  • 1
  • 8
  • 23

2 Answers2

0

Rewrite your struct as

struct trace
{
    …
};

The problem with your existing code is you've defined an anonymous struct and a typedef for trace that refers to that struct. This means there is no type struct trace, so your line struct trace traces[NUM_TRACES] is referring to a non-existant type.

You could also define your struct as

typedef struct trace
{
    …
} trace;

if you want, which would give you both trace and struct trace, but there's not really any point.

And of course you could keep your current type and just say trace traces[NUM_TRACES] instead.


Your line of code traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0 }; is also incorrect. The compiler is interpreting this as a declaration of a zero-length array without a type. If you want to initialize the traces array you must do it in an actual initializer, as in

struct trace traces[NUM_TRACES] = { {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0} };

(if NUM_TRACES is greater than 1 this will leave the rest of the array zero-initialized)

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • Ah okay, that makes sense, I've fixed the struct declaration I think, but I'm still getting the same errors, is there something else I'm missing? – Indigo Sep 08 '17 at 19:37
  • 1
    @Indigo Is your code sample exactly as written? It looks like you're saying `traces[0] = {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0 };` at the top level, but you can't write that at the top level, because that's a line of code, not a declaration. The errors you're getting are the compiler insisting on trying to interpret it as a declaration (of a zero-length array) without a type. – Lily Ballard Sep 08 '17 at 19:38
  • 1
    @Indigo Instead you can say something like `struct trace traces[NUM_TRACES] = { {GPIO_Pin_3, GPIO_Pin_7 , GPIO_Pin_0} };` This should leave all entries past the first one as zeroes. – Lily Ballard Sep 08 '17 at 19:41
  • Oh, wow, I think I've been writing too much python lately. Your last comment worked perfectly! – Indigo Sep 08 '17 at 19:46
0

You are using a type struct trace for which you have not provided a definition. You can do some things with such a structure type, but not anything that requires the system to know the size or members.

What you did define was a tagless structure type, aliased by type name trace. Because it is tagless, that type can only be referenced via the defined alias:

/* no struct */ trace traces[NUM_TRACES];

Alternatively, you could use your original array declaration if you in fact declared a structure type with tag trace:

struct trace
{
    uint32_t upstream_pin;
    uint32_t dnstream_pin;
    uint32_t led_pin;
} /* no instances declared here in this case */ ;

Note in particular that you do not need typedef to declare a structure type; its purpose is to declare type name aliases. You could, however, define a tagged structure type and an alias for it in one go, so that you could refer to it either with or without the struct keyword:

typedef struct trace
{
    uint32_t upstream_pin;
    uint32_t dnstream_pin;
    uint32_t led_pin;
} trace ;

I don't really recommend that, though -- it is stylistically better to choose one form to use (struct <tag> or aliased_type_name), and stick with it.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157