Issues with getting code to compile.

I get a bunch of errors when trying to compile some code I have written to log temperatures into the EEPROM.

I have declared a structure & variable:

struct LogModel {
  unsigned int time;
  int temperature;
  int humidity;
} logRecord;

I get a whole host of errors:

jLogger:11: error: 'LogModel' was not declared in this scope
jLogger:11: error: 'record' was not declared in this scope
jLogger:11: error: expected primary-expression before 'int'
jLogger:11: error: initializer expression list treated as compound expression
jLogger:12: error: 'LogModel' was not declared in this scope
jLogger:12: error: 'record' was not declared in this scope
jLogger:12: error: expected primary-expression before 'int'
jLogger:12: error: initializer expression list treated as compound expression
jLogger.ino: In function 'int readLog(LogModel*, int)':
jLogger:43: error: 'int readLog(LogModel*, int)' redeclared as different kind of symbol
jLogger:11: error: previous declaration of 'int readLog'
jLogger:47: error: expected ';' before 'int'
jLogger.ino:49: warning: comparison between signed and unsigned integer expressions
jLogger.ino: In function 'int writeLog(LogModel*, int)':
jLogger:56: error: 'int writeLog(LogModel*, int)' redeclared as different kind of symbol
jLogger:12: error: previous declaration of 'int writeLog'
jLogger.ino:63: warning: comparison between signed and unsigned integer expressions
jLogger.ino: In function 'void initializeLog()':
jLogger:78: error: 'writeLog' cannot be used as a function
jLogger.ino: In function 'void setup()':
jLogger:328: error: 'readLog' cannot be used as a function

How can I better match these errors to my code? Is there an intermediate file I can look at? I read somewhere that Arduino/Wiring is trying to create prototypes for me. That would explain the early line numbers (prior to where I declared these functions).

Thanks,
Jon
w1jp

Do you need to declare what datatype struct LogModel is?
Like int, or signed int?
If that's the case, a lot of those errors will go away.

The structure is a declaration of type.

In this case I am creating a variable of type LogModel

 LogModel logRecord; // variable logRecord of type LogModel

Later on in my code I create another variable:

 LogModel * record;

And you see references in the error stream above to 'record'.

I then typecast the LogModel* to a byte*.

...
record = &logRecord;
...
byte * eeData = (byte*)record;

This is so I can read/write bytes to the EEPROM with eeData[] semantics.

I create two utility functions:

int readLog (LogModel * record, int index);
int writeLog (LogModel * record, int index);

I use these to read and write the logRecord variable to EEPROM.

While I am new to wiring/arduino, I have been doing embedded C development for decades.

What I don't understand is how to tell wiring to ignore a block and not attempt to create prototypes (I can do that myself).

If you want to avoid the "helpful" prototype creation, make a new tab in the IDE, call it something.cpp and put your code into that. Then call whatever functions you want in it from the "main" tab.

w1jp:
Is there an intermediate file I can look at?

Turn on verbose compiling. You will see the various file names. I find that putting structs into a separate .h file tends to solve such problems (make a new tab in the IDE).

Oh thanks@nick...

I found the intermediate jLogger.cpp file...

Here is the excerpt from the beginning of that file.

#line 1 "jLogger.ino"
/*  130808
    jLogger is an application that will read temperature and humidity from 
    an SHI 11 and an MCP9700A and log it into memory logbook (EEPROM)
*/

#include <EEPROM.h>
// TYPES
// EEPROM data strcutre
#include "Arduino.h"
void delaySeconds(int seconds);
int readLog(LogModel* record, int index);
int writeLog(LogModel * record, int index);
void initializeLog();
void startSHTtransmission();
void sendSHTbit(int b);
int readSHTtemperature();
void usage();
void setup();
void loop();
#line 9
struct LogModel {
  unsigned int time;
  int temperature;
  int humidity;
} logRecord;

// CONSTANTS
const int SAMPLE_PERIOD = 10;    // seconds between samples
const int SAMPLES = 5;
...

I see what the issue is here. They create the forward declarations for me but 1) omit the structure LogModel definition and 2) place the prototypes in front of the structure definition.

So you say that I have to move the structure definition.

Put the structure into a .h file is the simplest.

Update

Ok, I moved this structure into its own tab "LogModel.cpp"

struct LogModel {
  unsigned int time;
  int temperature;
  int humidity;
};

...and I am still getting the same errors...

jLogger:12: error: 'LogModel' was not declared in this scope
jLogger:12: error: 'record' was not declared in this scope
jLogger:12: error: expected primary-expression before 'int'
jLogger:12: error: initializer expression list treated as compound expression
jLogger:13: error: 'LogModel' was not declared in this scope
jLogger:13: error: 'record' was not declared in this scope
jLogger:13: error: expected primary-expression before 'int'
jLogger:13: error: initializer expression list treated as compound expression
jLogger:27: error: 'LogModel' was not declared in this scope
...

This didn't work.

Zip up your project and post it as an attachment. I did say .h not .cpp.

SUCCESS!

putting it a tab called "LogModel.h" and adding

#include "LogModel.h"

worked.

Net for everyone:
Arduino/Wiring appears to create forward declaration prototypes automatically; however, it doesn't do a consistent job of it.

Moving the structure into a new tab (and new file) with a .h extention. Adding an #include "myfile.h" will place it above the auto-declared prototypes.

w1jp:
SUCCESS!

putting it a tab called "LogModel.h" and adding

#include "LogModel.h"

worked.

Net for everyone:
Arduino/Wiring appears to create forward declaration prototypes automatically; however, it doesn't do a consistent job of it.

Moving the structure into a new tab (and new file) with a .h extention. Adding an #include "myfile.h" will place it above the auto-declared prototypes.

UECIDE has an option to turn that "feature" off :stuck_out_tongue:

w1jp:
Arduino/Wiring appears to create forward declaration prototypes automatically; however, it doesn't do a consistent job of it.

That is putting it mildly! It's a bad idea poorly implemented, and the only reason it doesn't cause more trouble than it already does is that Arduino is designed for novices that don't use complicated and frightening things like structs and classes. (Somebody quoted a comment from one of the Arduino developers who actually said that, although not in those exact words.)