syntax driving me crazy

Hi, I am new to Arduino and having some issues with the following:

typedef struct
{
int thing;
} ANEWTYPE;

void doessometing(ANEWTYPE *x)
{
x->thing=0;
}

void setup(void)
{
}

void loop(void)
{
ANEWTYPE x;

doessomething(&x);
}

first of all... the code above gives me the follwoing error in the Arduino environment...

error: variable or field 'doessometing' declared void In function 'void doessometing(ANEWTYPE*)':
In function 'void loop()':

if I changed the function definition of 'doessomething to:

int doessometing(ANEWTYPE *x)
{
x->thing=0;
}

then that particular issue is fixed but then I get the following:

error: 'ANEWTYPE' was not declared in this scope In function 'int doessometing(ANEWTYPE*)':
In function 'void loop()':

So, I have two issues. I am an old time programmer and I have either forgotten something fundamental or done something plain dumb. Please help.

The Arduino IDE automatically generates prototypes for your functions. Unfortunately, this doesn't work for functions whose arguments or return value are types defined in the sketch, since the prototypes get inserted above the type definitions. I'm not sure there's really a good workaround for this.

what about making this as a library? from what i understand, arduino doesnt do much with libraries other than include them.

Hi...

The Arduino IDE automatically generates prototypes for your functions. Unfortunately, this doesn't work for functions whose arguments or return value are types defined in the sketch, since the prototypes get inserted above the type definitions.

Hmmm, this strikes me as a fairly significant issue for more "advanced" use of the IDE--it also makes me think it might explain an issue I had a while back...

I'm not sure there's really a good workaround for this.

While I really like not having to declare prototypes, from some of the comments you've made in response to odd errors people are getting it seems like there's a point at which the auto-prototyping may become a hindrance rather than a help. (If the price I have to pay for auto-prototypes is never knowing if my code or the auto-proto-generator is at fault it seems a fairly high price.)

I wonder about possible solutions:

  1. Improving the auto-prototype generation--presumably not a totally straight forward task... :slight_smile: (Assuming it's currently only a single-pass process, would a two-pass process work any better for the edge cases?)

  2. Document (and include error messages?) for known failure states. (Or a "lint" type tool that would alert you to possibly problematic code...)

  3. Have the prototypes integrated into the IDE more?

I realise that the issues probably mostly arise when one is trying to do more advanced coding techniques but if we want to encourage people to continue to use the IDE at all user levels then I think the issue has some significance...

My 2 cents...

--Phil.

I agree that it's an increasingly important issue. While we don't document (or necessarily encourage) the declaration of custom types within a sketch, I understand that people coming from a C/C++ background will want to.

The current system uses a regular expression, which is not very reliable. Probably the best thing to do is use the preprocessor to identify the functions that need prototypes. It would also be good to be more intelligent about where we place them. Just sticking them underneath any #include's might be a reasonable start, as then you could declare your custom data types in a header file in another tab in your sketch.

As with most features affecting more advanced Arduino users, this is something I look to the community to help with, as the affected users are those most able of providing a solution. Anyone want to take a shot at it? I'll be happy to point you in the right direction.

Documenting the known failures is a great idea. I'll try to add it to the troubleshooting guide. Do have links to other relevant forum posts handy?

Hi Guys, thanks for the banter so far. I think your thread explains the second isue but not the first contained in my original post. Anyone got any ideas why chaning 'void' to 'int' shuts up the compiler?? Adding to the discussion, I am with 'follower', the auto proto stuff is a massive price to pay. These little porcessors and indeed the Arduino are capable of some serious stuff. They have enough program space to contain significant code. For this reason, excluding or 'discouraging' custom types means that your code relies on a huge number of global variables or functions with parameter lists that are too long. The concept of modular code is seriously damaged. In either case, this is a recipe for disaster and unreadable code. Are you sure there is not a work around?? Toss the auto proto stuff please..... or at least make it an option. I will otherwise have to leave the IDE to do useful stuff.

The current system uses a regular expression, which is not very reliable.

Heh, that explains a lot. :slight_smile: I notice that the IDE seems to already be using ANTLR for something (given Arduino 10.app/Contents/Resources/Java/antlr.jar) so perhaps it would make sense to use it as the basis?

Probably the best thing to do is use the preprocessor to identify the functions that need prototypes.

I made a note of some links related to parsing C/C++ in Java.

I suspect "find functions" is probably a "solved problem" to some degree--but anything short of a fully correct parser is likely to cause more issues, but hopefully with the limited amount of C++ used in the IDE we can stop short of that. Certainly we should be able to handle two-word return types, comments and, I would think, custom types.

It would also be good to be more intelligent about where we place them. Just sticking them underneath any #include's might be a reasonable start, as then you could declare your custom data types in a header file in another tab in your sketch.

Hmmm, that's a good point--if custom types aren't defined in a known place then it's not going to be straight-forward to know where to put the function declarations. You could get fancy I guess with trying to insert the declarations in a place that's before all uses but after any required definitions, but that sounds complicated...

Documenting the known failures is a great idea. I'll try to add it to the troubleshooting guide.

Thanks for adding that--would be good to add actual example error messages as we notice them so they are find-able via Google.

--Phil.

Bloke,

I am attempting the same thing, declaring a structure type then using it as an argument in a function call. Seems like the administrator said what I just found...glad I decided to check the forum for answers - sarcasm!

Since no answers exist, I will make my own.

I decided for my function, to not pass the new structure as an argument, but to pass a void pointer as my argument. Then, create a variable of the new type, and set it equal to the typecasted void pointer (typecasted as your new struct).

For you this means (and this is an example for one way to do it)

void doessometing(void ptr)
{
/
a variable of new type */
ANEWTYPE *x;

/* set x = "typecasted" ptr to fix stupid auto-prototyping compile error*/
x = (ANEWTYPE *)ptr;

x->thing=0;
}

This will get you passed the compile error. Let me know if it works. I am awaiting my boards to arrive next week. I wont know until then.

Cheers.

what about making this as a library? from what i understand, arduino doesnt do much with libraries other than include them.

I have yet to play with the software / hardware (no boards yet) , but would including the library (where the typedefs etc reside) work to fix this auto-prototyping issue with user defined typedefs?

Be easy if someone answered this for me than for me to spend any more time on it.

I don't think putting the type declaration in a library would help, since the automatically generated prototypes would appear above the #include for the library. But I haven't it tried it, so I'm not sure.

Mellis,

Thanks. I didnt think so either, worth a try to ask.

Kev

I had a related problem with passing a structure typedef as a parameter, I tried the typedef in a library and it didn't work. I solved my problem by wrapping the structure elements in a class. This works either as a class in the sketch or as a library. The class overhead seems small (it looks like 8 bytes per instantiation, plus of course whatever the class explicitly consumes).

I don't know if that approach works for what you want to do.

Passing pointers to user defined types can be very useful, so I for one would welcome the option to turn off auto prototyping. Perhaps a pragma (something like: 'Disable auto function prototyping') so the default was still newbie friendly.

Thanks to everyone who contributed here. Interresting idea oneilka although goes against the grain to get around the issue. I have finally had some time to come back to the issue. Hiding it as a library does indeed solve the problem. I also stand by my original comment in that the basic issue does have to be addressed. A ibrary is fine if you have a tried and tested piece of code but it is a pain to modify or develop when linked this way.

I ran into this problem, and eventually I found my way into this thread. I begun pulling down the sources for the IDE so that I could add a menu option to disable the auto-prototyping, however a simple workaround struck me: I put /* pants */ before the function (so it becomes /* pants */ int blah(char foo) {), and this solved the issue. Presumably because the IDE no longer picks it up as a function.

I think that auto-prototyping is okay as long as it's either toggleable or rock solid. C++ is one of the hardest languages to parse properly, I'm going to suggest using something like gcc-xml (http://gccxml.org) which can parse C++ into XML, which should make things easier. Alternately implement a basic parser in ANTLR or some other parser toolkit. Regular expressions will only take you so far.

Improving the auto-generation of prototypes in definitely high on the priority list, though I haven't settled on a strategy yet. There's apparently a cproto program, but I'm wary of including yet another binary in the distribution. Some other tools have problems with non-compilable code (e.g. code that's missing function prototypes). I hope to have something done for Arduino 0011. Patches welcome. :slight_smile:

I hope you can include an option to turn auto prototyping off, particularly if you think a robust solution to the existing prototyping problem may not make it into the next release.

Rewriting the code from the original post as follows will work:

typedef struct a_new_type
{
int thing;
} ANEWTYPE;

void doessometing(struct a_new_type *x)
{
x->thing=0;
}

void setup(void)
{
}

void loop(void)
{
ANEWTYPE x;

doessomething(&x);
}

I need to make a correction to my last reply.

ANYTYPE x;

has to be declared outside of loop()

What is the main idea behind Arduino's language?
Why don't you use plain C or C++?

It is plain C/C++, with the one exception of automatically generating prototypes for functions. At the moment, that process is not particularly robust, and that's a problem - one that should be fixed in the next release. Other than that, your code is passed straight to avr-gcc or avr-g++.