Automatic function pro typing stoped working.

One of the things I like about the Arduino IDE is the automatic generation of function prototyping. This means you can start of the sketch with setup and loop and then follow it with the function definitions.
However, I have come across something that seems to jam this process.

I am playing about with OSC messages and I downloaded this library:-

After hacking about a bit I found this minimal sketch which I think broke the automatic generation of function prototyping:-

#include <OSCBundle.h>
#include <OSCBoards.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial);
#endif

void setup(){
  Serial.begin(38400);
  Serial.println("Hi");
}

void loop(){
  blink();
}

void blink(){
  digitalWrite(13,LOW);
  delay(600);
  digitalWrite(13,HIGH);
  delay(600);
}

This gives the error message

Arduino: 1.0.5 (Mac OS X), Board: "Arduino Uno"
sketch_dec12a.ino: In function 'void loop()':
sketch_dec12a:23: error: 'blink' was not declared in this scope

Has anyone any idea why this broke the IDE?

That's curious, because one of the things I hate about the IDE is that daft auto prototyping. I might be more tolerant if it actually worked properly, but to add insult to injury the implementation is pretty useless too.

I suspect in this case the prototype is being inserted in the wrong place and is falling foul of your preprocessor conditional sections. You could confirm that by looking at the generated C++ source in the temporary directory.

I suspect in this case the prototype is being inserted in the wrong place and is falling foul of your preprocessor conditional sections.

Yep. You can add:
byte stuffGetsAddedAfterThis;
as the first line of the sketch to give the IDE a clue where it SHOULD insert stuff.

Where it actually inserts stuff is after the first non # line of the sketch, regardless of what those # lines are.

Thanks for the explanation.
This worked (restored the auto prototyping) :-

#include <OSCBundle.h>
#include <OSCBoards.h>

byte led = 9;

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial);
#endif

where as this didn’t

#include <OSCBundle.h>
#include <OSCBoards.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial);
#endif

byte led = 9;

The prototypes get inserted just before the first non-blank line that isn’t a #watever. In your code it would be where I have indicated:

#include <OSCBundle.h>
#include <OSCBoards.h>
#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
// <--------------- Prototypes inserted here
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial);
#endif

byte led = 9;

So your blink prototype would be only available on a board which has USB serial.

Suffice it to say, UECIDE has an option to turn off that pesky prototype insertion rubbish so you can do it manually.

Thanks. Making more sense.

Grumpy_Mike:
Thanks. Making more sense.

I'm working on a new method of doing the prototyping and preprocessing at the moment, by using gcc to do an initial preprocessing of the .ino into a cleaned up .cpp file, which will expand any macros, remove any comments, etc. Once that is done there will only be #includes left as preprocessor directives. Then I need to get it to work out where the first function is, so it can put the prototypes after any struct / typedef constructs... All fun... :wink:

What're you planning to do if people scatter the types and functions arbitrarily in the source? How about when they don't put them in dependency order? (Because - why would you need to declare things in any particular order? The Arduino IDE hand-waves all that stuff away, right?)

Trying to auto-generate the declarations is fundamentally daft IMO and also quite hard to do in a way that removes all responsibility from the programmer. The rules for declaring things before you use them are simple, obvious and widely accepted in the 'C'/C++ world. At the end of the day C++ is not Java and Wiring is not Processing, no matter how much the Arduino IDE designers might try to fool you otherwise. It's just C++. There's nothing special about it and no need to try to protect Arduino developers from needing to understand it; the attempt to do that is just making the problem worse because now the behaviour of the code is unique to Arduino, and non-obvious, and broken.

PeterH:
What're you planning to do if people scatter the types and functions arbitrarily in the source? How about when they don't put them in dependency order? (Because - why would you need to declare things in any particular order? The Arduino IDE hand-waves all that stuff away, right?)

Trying to auto-generate the declarations is fundamentally daft IMO and also quite hard to do in a way that removes all responsibility from the programmer. The rules for declaring things before you use them are simple, obvious and widely accepted in the 'C'/C++ world. At the end of the day C++ is not Java and Wiring is not Processing, no matter how much the Arduino IDE designers might try to fool you otherwise. It's just C++. There's nothing special about it and no need to try to protect Arduino developers from needing to understand it; the attempt to do that is just making the problem worse because now the behaviour of the code is unique to Arduino, and non-obvious, and broken.

While I completely agree with you, and that is exactly the reason UECIDE has the option to turn it off in preferences, the Arduino needs it so it can keep teaching novices bad habits. After all, that's what the Arduino is all about, right? Hide reality from n00bs, so that when they go into a real work environment with real tools they have a massive culture shock and don't have a clue what they're doing?

But still, there's better ways of doing it than the Arduino IDE do it - granted not perfect, but then, as you say, nothing will be perfect short of rewriting the C structure - but better nontheless (for those that still need the crutch).