Struct Not Defined in this Scope?

So, yes, I’m feeling like a n00b, so I come crawling in humility for a bit of guidance from the masters…

The following stripped down code, when compiled, gives a bunch of errors about PartSpec_t not being declared in this scope. Here are the exact errors:

StructError:1: error: ‘PartSpec_t’ was not declared in this scope
StructError:1: error: ‘part’ was not declared in this scope
StructError:2: error: ‘PartSpec_t’ has not been declared
StructError.cpp: In function ‘void loop()’:
StructError:12: error: ‘TimeFromPartSpec’ cannot be used as a function
StructError:14: error: invalid initialization of reference of type ‘int&’ from expression of type ‘PartSpec_t’
StructError:2: error: in passing argument 2 of ‘void SetTimeElementsFromPartSpec(tmElements_t, int&)’
StructError.cpp: In function ‘time_t TimeFromPartSpec(PartSpec_t&)’:
StructError:17: error: ‘time_t TimeFromPartSpec(PartSpec_t&)’ redeclared as different kind of symbol
StructError:1: error: previous declaration of ‘time_t TimeFromPartSpec’
StructError:19: error: invalid initialization of reference of type ‘int&’ from expression of type ‘PartSpec_t’
StructError:2: error: in passing argument 2 of ‘void SetTimeElementsFromPartSpec(tmElements_t, int&)’

And here’s the code (also attached):

#include <Time.h>

// Types
typedef struct {
  int current_value[6];
} PartSpec_t;

void setup() {
}

void loop() {
	PartSpec_t part;
	time_t a_time = TimeFromPartSpec(part);
	tmElements_t elements;
	SetTimeElementsFromPartSpec(elements, part);
}

time_t TimeFromPartSpec(PartSpec_t& part) {
  tmElements_t elements;
  SetTimeElementsFromPartSpec(elements, part);
  time_t to_time = makeTime(elements);
  return to_time;
}

void SetTimeElementsFromPartSpec(tmElements_t to_elements, PartSpec_t& part) {
  to_elements.Year = y2kYearToTm(part.current_value[0]);
}

I’d be grateful for any guidance.

Mike

StructError.pde (563 Bytes)

Welcome.

The problem is that the Arduino IDE parses your sketch, extracts function prototypes, and moves them to the top. Your sketch (roughly) becomes this…

#include <Time.h>

time_t TimeFromPartSpec(PartSpec_t& part);
void SetTimeElementsFromPartSpec(tmElements_t to_elements, PartSpec_t& part);

// Types
typedef struct {
  int current_value[6];
} PartSpec_t;

void setup() {
}

void loop() {
   PartSpec_t part;
   time_t a_time = TimeFromPartSpec(part);
   tmElements_t elements;
   SetTimeElementsFromPartSpec(elements, part);
}

time_t TimeFromPartSpec(PartSpec_t& part) {
  tmElements_t elements;
  SetTimeElementsFromPartSpec(elements, part);
  time_t to_time = makeTime(elements);
  return to_time;
}

void SetTimeElementsFromPartSpec(tmElements_t to_elements, PartSpec_t& part) {
  to_elements.Year = y2kYearToTm(part.current_value[0]);
}

Probably the best solution is to create a second tab (header file) containing the PartSpec_t definition.

The problem is that the Arduino IDE parses your sketch, extracts function prototypes, and moves them to the top. Your sketch (roughly) becomes this...

Except when the function contains reference arguments. In these cases, the IDE fails to create a prototype. Since both of your functions use reference arguments, no prototypes are created.

Try moving the functions before they are referenced (i.e. before loop()).

Moving the struct definition to a separate .h file did the trick!

Thank you so much!

Mike

Another way of overriding the automatic creation of a function prototype in the wrong place is to create one yourself in the right place. Then you don’t need a separate header.
For example in my code where I hit the same issue:

typedef struct tIR
{
IRSensor left;
IRSensor right;
int pinIRcontrol;
} IR;

IR IRsystem;

void ReadIRSensors(IR s); / without this line, you get "error: ‘IR’ was not declared in this scope */

void ReadIRSensors(IR *s)
{
s->left…

PaulS: Except when the function contains reference arguments. In these cases, the IDE fails to create a prototype. Since both of your functions use reference arguments, no prototypes are created.

Yet another reason to always explicitly provide your own prototypes for all functions. That way you know the IDE won't screw things up trying to "help" you.