Struct as argument

I have the following struct:

struct key {
int board;
int value;
int type;
};

And I need to create a function

void assignToBoard(key &obj1, analogMultiplexer &obj2) {
//This function assigns your table object to some multiplexer board, so every key will be mapped.

}

that receives an array of struct objects and assigns it to a analogMultiplexer object. The problem is that when I compile I get:

zanella_launchpad:18: error: variable or field 'assignToBoard' declared void
zanella_launchpad:18: error: 'key' was not declared in this scope
zanella_launchpad:18: error: 'obj1' was not declared in this scope
zanella_launchpad:18: error: expected primary-expression before '&' token
zanella_launchpad:18: error: 'obj2' was not declared in this scope

but when I take
void assignToBoard(analogMultiplexer &obj2) {

(without the key object) it compiles.
I don't understand what I'm doing wrong since I declared 'key' before the void assignToBoard.

Try putting your struct into a header file and #include-ing it. It's probably the auto-generated function prototypes that the IDE inserts that's causing the error.

You need to post ALL of your code.

The IDE does not create function prototypes for functions that take reference arguments. There is (yet) no proof that you did, either.

Generally, struct definitions work better when they are defined in a header file.

I need to understand it better. Why do I need a function prototype if both key and analogMultiplexer are visible to the assignBoard()? Why the IDE does not create function prototypes for functions that take reference arguments? Could you give me an example? I don't need only the code to work, but I need to understand what's happening. Thanks!

This seems to be an area where the Arduino IDE is not smart enough.

I spent ages trying to use a struct as a parameter until I took the trouble to read the relevant learning page. See the FAQ piece.

...R

Nice, thanks man. But I transformed the struct in a class and still got problems! Do I need to declare it in a .h file too? :frowning: didn't want to do it.

Afraid your problems are because of misunderstanding of some fundamental C programming ideas.. or even programming ideas.

I have the following struct:

struct key {
int board;
int value;
int type;
};

does not create a variable its a struct definition i.e how you want to group the data would advise you use..
form its more obvious for newbie..

typedef struct {
int board;
int value;
int type;
} key; // now it is obvious you have defined a new variable type but not the variable

key myKey; // now the variable mykey exist of type key

myKey.board = 9; // thats how to get to items inside notice the dot

Functions and why prototypes

They are historic but they are still important to the compile process they ensure that the compiler understands what parameters you are passing this is called semantics checking,

Take the sentance in English
I rode my horse across the English Channel. -- there's nothing wrong with this as English, so unless you know the English Channel is water it seems acceptable. Same argument for prototypes even if they are in same file..

They are sometines a pain for instance

void func1(void); // still need a prototype even though nothing in or out..

Happy Coding...

tgsuperspec:
Afraid your problems are because of misunderstanding of some fundamental C programming ideas.. or even programming ideas.

I have the following struct:

struct key {
int board;
int value;
int type;
};

does not create a variable its a struct definition i.e how you want to group the data would advise you use..
form its more obvious for newbie..

typedef struct {
int board;
int value;
int type;
} key; // now it is obvious you have defined a new variable type but not the variable

key myKey; // now the variable mykey exist of type key

myKey.board = 9; // thats how to get to items inside notice the dot

Not strictly true. While that held true for C, C++ does the typedef of a struct for you.

struct key {
  int board;
  int value;
  int type;
};

key foo;

is perfectly acceptable in C++.

I did not say it was not acceptable but having lectured c and c++ to newbies ysing the typedef route more clearlydefines what a structure is..

tgsuperspec:
I did not say it was not acceptable but having lectured c and c++ to newbies ysing the typedef route more clearlydefines what a structure is..

So does appending the commonly used _t to signify a typedef... It should really be key_t...

All these _ etc are conventions you can use or not use they have no true meaning in the language specifications

Many commanys have there own ideas, MicroSoft 10 years or so ago used so called Hungarian notation . where variable names tried to describe themselves for program documentation..

Naming conventions are a modern idiom, but names are better than callingvariable a,b.c etc only..

tgsuperspec:
All these _ etc are conventions you can use or not use they have no true meaning in the language specifications

Many commanys have there own ideas, MicroSoft 10 years or so ago used so called Hungarian notation . where variable names tried to describe themselves for program documentation..

Naming conventions are a modern idiom, but names are better than callingvariable a,b.c etc only..

I'm so glad they dropped Hungarian notation with .NET... However, I know some ex-Microsoft developers who even now STILL use Hungarian notation, and it bugs the hell out of me! Horrible idea...

I do remember when all I had at my disposal was variables A-Z and A$-Z$ and floating point was non-existant... Those were the days...

But we digress...

In C and C++ things always have to be declared before they can be used. That "before" means lexically in the file - i.e., higher up the page.

You can "forward" declare something in C and C++ by putting in what is called a "prototype" - i.e., something that says "I am going to further define this later on, but this is roughly what it will look like". For a function that might be:

void function b(); // This is the prototype

void function a() {
  b();
}

void function b() {
  // ...
}

Function B is defined after function A, yet function A wants to call function B, so it need to know about it, so a prototype is added before function A to tell it that function B will be defined later.

You don't need to do any of that on the Arduino because the IDE does it all for you - it scans through your sketch looking for functions and builds up a list of prototypes which it then inserts into the top of your sketch after any #includes.

Now, if one of those functions has your own typedef or struct in it, where that typedef or struct is defined at the top of your sketch, the prototype (using that typedef or struct) will be inserted before the typedef or struct is defined, and the IDE isn't clever enough to know any better. So, it throws a wobbly because it doesn't know what the variable types in the prototypes are.

By moving the typedefs or structs into a header file and #include-ing them into your sketch at the top you are forcing those definitions to occur before where the prototypes are inserted.

Only one comment if you get to a system beyond the capabilities of the Arduino IDE I have on two occassions and have to use one of the third party interfaces into Xcode on Mac or the VStudio version for PC. tou have to conform to the ISO standard with a h file.

The IDE for arduino actually makes for lazy programmers and in some cases very poor code...

and it bugs the hell out of me!

typedefs are worse. Just what the hell is a LPCTSTR?

PaulS:

and it bugs the hell out of me!

typedefs are worse. Just what the hell is a LPCTSTR?

Hmm... LPC... the closest I can think of for that is Lars Pensjö's C (predecessor to Dwarkin's Generic Driver). STR is probably String, so that leaves the T... Hmmm... Towel...?

A string of towels defined in LPC?

A string of towels defined in LPC?

Funny. It's really a long pointer to constant string (NULL terminated array of TCHAR). And what is a TCHAR? Well, depending on what compiler options you've set, it's either char or _wchar.

What the significance of the _ is escapes me. Another brain dead type from the idiots in Redmond.

PaulS:

A string of towels defined in LPC?

Funny. It's really a long pointer to constant string (NULL terminated array of TCHAR). And what is a TCHAR? Well, depending on what compiler options you've set, it's either char or _wchar.

What the significance of the _ is escapes me. Another brain dead type from the idiots in Redmond.

Maybe it makes the wide char even w_i_d_e_r?

tgsuperspec:
The IDE for arduino actually makes for lazy programmers and in some cases very poor code...

Yes. The IDE and runtime library are clearly aimed at novices and make it very easy to implement 'hello world' applications but do not support or encourage good programming practices. Partially I'm sure that's because it was deliberately aiming to dumb the development process down for novices, but in my opinion that only accounts for some of the mistakes in Arduino. In my opinion it ends up confusing novices and teaching them bad habits, which is unfortunate.

Totally agree..... 8) 8)

the embeded scripts for xcode is brilliant...

Thanks by all the conversation, I'm learning through this too :slight_smile:

But could you explain just one more thing? If I write

void assignToBoard(analogMultiplexer &obj2) {

it compiles. The analogMultiplexer class is outside, in a .h file. Is this the problem? I can't have classes in the same page of the code? Why? I remember that I can do it in a general c++ code.

Thank you!