Passing Object to function

Why will this not compile, I believe it is plain enough c++.
Passing an object reference to a function is very important to my coding style :slight_smile:

class John
{
    public:
    int a;
};

John j;

// the Following line in Arduino 1.0.2 causes:
// error: 'John was not declared in this scope
void doJohn(John & j1){  int i=j1.a;    }  

void setup()
{
    John &j2(j);  // this works ok
    int i= j2.a;
}

void loop()
{

}

If you put the definition of the class in a header file, and include that file in the sketch, the code compiles.

johncc:
Why will this not compile, I believe it is plain enough c++.

The problem is in the 'mucking about' that Arduino does with your code before compiling it. If you have functions that are not prototyped then it creates prototypes for you and puts them in front of your code. In this case, that means before your type/class declarations. The declarations are inserted after your #includes, so one way to avoid the problem is to put the prototypes in a #included file.

It also compiles if you change:

void doJohn(       John & j1){  int i=j1.a; }

to

void doJohn(class John & j1){  int i=j1.a; }

This trick works for 'struct' so I gave it a try with 'class' and it worked. Probably works with 'enum', too.

johnwasser:
It also compiles if you change:

I wasn't aware that worked too. Does it implicitly declare 'class John;'?

PeterH:

johncc:
Why will this not compile, I believe it is plain enough c++.

The problem is in the 'mucking about' that Arduino does with your code before compiling it. If you have functions that are not prototyped then it creates prototypes for you and puts them in front of your code. In this case, that means before your type/class declarations. The declarations are inserted after your #includes, so one way to avoid the problem is to put the prototypes in a #included file.

Very good explanation, Thank You!

John

johnwasser:
It also compiles if you change:

void doJohn(       John & j1){  int i=j1.a; }

to

void doJohn(class John & j1){  int i=j1.a; }

This trick works for 'struct' so I gave it a try with 'class' and it worked. Probably works with 'enum', too.

Oh that's a great point. I should have tried that myself!

Cheers,
John

PeterH:

johnwasser:
It also compiles if you change:

I wasn't aware that worked too. Does it implicitly declare 'class John;'?

I suspect it just provides enough context for the compiler to make a valid forward reference. If later the type "John" was declared as something else (struct John, or typedef int John) the compiler would likely complain.