Paassing structs to functions (error: "variable or field declared void).

I'm working on a project where I've put some parts of the code in separate header files to try to organize it better. Passing single variables to functions seems to work fine, but I get the error message "variable or field 'addTwo' declared void" (see code below), when trying to pass a struct containing several variables. A small example is shown below. If I put the struct inside "test.h" it works fine, but I want the struct to remain in sketch.ino.

sketch.ino:

#include "test.h"

int number = 5;

struct numberSTRUCT {
  int a = 2, b = 3;
} numbers;

void setup() {
  addOne(&number);
  addTwo(&numbers);
}

void loop() {
}

header file:

void addTwo(numberSTRUCT *num){
  *num->a += 2;
  *num->b += 2;
}

void addOne(int *num){
  *num +=1;
}

why the h*ll when adding two it would look like this

  *num->a += 2;
  *num->b += 2;

but when adding one it would look like this  *num +=1;How can this make any sense at all?

also if num in the function is a pointer to a numberSRUCT, what do you think *num-> would represent? think about it…

(there would be other things to say (default values, I doubt it even compiles in one file or that “If I put the struct inside “test.h” it works fine” as you say) but this one just jumps out to me…)

include puts a copy of the included fine into the file which includes it.

Your must have the definition of the struc in both!

Mark

You are also mis-using & read this c faq

Mark

J-M-L: why the h*ll when adding two it would look like this

  *num->a += 2;
  *num->b += 2;

but when adding one it would look like this

  *num +=1;

How can this make any sense at all?

also if num in the function is a pointer to a numberSRUCT, what do you think *num-> would represent? think about it...

(there would be other things to say (default values, I doubt it even compiles in one file or that "If I put the struct inside "test.h" it works fine" as you say) but this one just jumps out to me...)

My understanding was that when accessing variables inside structs when passing them to functions you must use "->" instead of the "." When I put the struct inside the header file it works fine.

Lars81: My understanding was that when accessing variables inside structs when passing them to functions you must use "->" instead of the "." When I put the struct inside the header file it works fine.

so I don't see a -> in *num +=1;

also if num is a pointer to the struct, then num->a is the proper syntax to point to a. if num is the struct then you use num.a

read some tutorials such as http://www.cprogramming.com/tutorial/c/lesson7.html (first answer from google, did not really double checked it but has structure and pointer access)

J-M-L: so I don't see a -> in *num +=1;

also if num is a pointer to the struct, then num->a is the proper syntax to point to a. if num is the struct then you use num.a

Should I use "->" when accessing a single variable? I thought I had to use "->" when accessing structs inside functions.

EDIT: I just realized that "num->a" is equivalent to (*num).a. Makes a little more sense now.

cf the small tutorial I pointed above - should clarify the concept for you

or here is another one C - Structures - Tutorialspoint this one is more step by step and deals with pointers too

J-M-L:
cf the small tutorial I pointed above - should clarify the concept for you

or here is another one C - Structures - Tutorialspoint this one is more step by step and deals with pointers too

Thanks.

Following the example under section “pointers to structures” (which is quite similar to my problem) in this link; what if I want the function printBook() to be inside the header file? It works fine when I write int inside the .ino file like this:

#include "printbook.h"

struct Books{
   int   book_id;
};


void printBook(Books *book){
Serial.println(book->book_id);
}

void setup() {
Serial.begin(115200);
delay(100);
Books book1;
book1.book_id = 1;
Books book2;
book1.book_id = 2;
printBook(&book1);
}

void loop() {
  // put your main code here, to run repeatedly:

}

But I want this:

#include "printbook.h"

struct Books{
   int   book_id;
};

void setup() {
Serial.begin(115200);
delay(100);
Books book1;
book1.book_id = 1;
Books book2;
book1.book_id = 2;
printBook(&book1);
}

void loop() {
  // put your main code here, to run repeatedly:

}
  • header file
#include <arduino.h>

void printBook(Books *book){
Serial.println(book->book_id);
}

books goes in printbooks.h !!!

Mark

holmes4: books goes in printbooks.h !!!

Mark

Okay then. :)

In my project the "printBook.h" contains quite a few functions and variables taking up a lot of memory so I was hoping it was possible to just not include it (in my project this is for printing data for debugging/tuning etc), but I still need access to the Struct inside the .ino file. If the struct then resides inside the header file I need to include all of it.

Really h in the .[color=red]h[/color] files is meant for header, not helper functions. I think it's a bad practice to be willing to put code into the .h

You might want to explore the extern keyword in C

Your code should look like this

.ino file

#include "books.h"

void setup(){
     setbooknumber(3);
}

void loop(){

     Serial.println(booknumber;
     booknumber++;
     delay(1000);

}

books.h

extern int booknumber;

void setbooknumber(int num);

books.c

#include "books.h"

int booknumber;

void setbooknumber(int num){
     booknumber = num;
}

Not compiled or tested!

Mark

holmes4: Your code should look like this ... Not compiled or tested!

clearly with Serial.println[color=red]([/color]booknumber;

:-)

Fixed code for ino

#include "books.h"

void setup(){
     setbooknumber(3);
}

void loop(){

     Serial.println(booknumber);
     booknumber++;
     delay(1000);

}

Mark

So, I was surprised that you can #include “books.h” in the “books.c” file because then the compiler essentially sees:

extern int booknumber;
int booknumber;

in the SAME file. But, it does compile. So, I learned something.

Previously, I thought ‘extern int booknumber;’ tells the compiler “There’s an integer variable named ‘booknumber’ out there somewhere, don’t worry about it the linker will find it later, don’t allocate any memory space for it". But, the statement ‘int booknumber;’ tells the compiler “I want an integer variable named ‘booknumber’ and please allocate memory space for it".

Those two statements seem in opposition to each other. Can someone please supply a reference as to how they are reconciled?

Thanks.

extern just tells the pre processor "if you don't know what this is, then here you go, use that definition but don't bother allocating memory for it because it's done elsewhere".

So the fact you really declare the variable a bit later is a confirmation of what you told the pre processor before. not a contradiction.

pre-processor not compiler?

How about reading about the four steps in compiling a C++ file, it will explain how/when the object code for the library functions are stitched in during linking.

http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html

All this is available on the interwebs

extern has nothing to do with the pre-processor.

It's a part of the syntax (the language proper) it tells the compiler (NOT the pre-processor) that the variable will be allocated space/memory but not as a result of compiling this .c/cpp file.

It's there to allow programs to be split over many files.

Mark