Why does this line need 'void'?

Unwise and wrong. You probably mean "declare in more than one place", and that isn't just OK, it is essential to be able to do that.

Think about how libraries and header files use that capability.

a7

The entire purpose of a prototype is to tell the compiler "There WILL be a function with this name, that takes these arguments, and returns this type. That function will be defined later". That information allows the compiler to compile code that calls that function, without yet knowing the contents of that function. Without the prototype, the compiler could not check that you are properly USING the function, without having the entire function defined BEFORE it is ever used. It's a pretty simple concept. As said, in most cases, the Arduino pre-processor will create prototypes for you, before it begins compiling your code. But the version of your code WITH the prototypes in it is kept in a temporary directory, so you will never see it unless you specifically look for it.

I was being more general in my statement. Its dangerous to define/declare/state/write down anything in two places (or more). And however if you must they must be identical.

Whether the compiler or some editor catches is irreverent.

Again IMHO

It is worth mentioning that the preprocessor is not perfect. I have had some challenges that kept me busy for, um, too long.

Although it isn't the first thing or maybe even the second or third, suspecting that the preprocessor has dealt you a bad hand is worth considering when it seems like you're in WTF land with you code.

Happened to me just the other day and I made it all the way here only to be reminded. Not of a flaw, just about how it actually works and how it needs to be kept in mind.

a7

If you make it a habit of always providing prototypes for all functions yourself, that will be one less thing able to cause a WTF moment. If one desires to move beyond the Arduino IDE (Eclipse-based for example), you'll have to do it anyway.

C++ (Language) is an amplification of C Language.
Arduino (Language) is a simplification of C++ Language.

Improved.

Is probably a good idea. Often the prototype is known before any code is written, in my work anyway, so just typing it up there woukd be easy and I am soooo lazy I deserve to be placed in hell for a little cool-out from time to time.

a7

Hey! There's an echo in here.

No! This is to comply with the language requirement that the function must be declared before the setup() function and then be defined after the loop() function.

The only requirement is that a function be declared (using a function prototype) or defined (i.e. implemented) in the translation unit before the first attempt to call it.

If a function prototype is used to fulfil the above requirement, there is no further restriction on the location of the function's implementation. It can go anywhere in the translation unit (or in a different translation unit).

If the function's implementation fulfils the above requirement, then there is no need to have a prototype for that function in that translation unit.

Can't it go "anywhere"? Like another source file entirely?

In C, I though a function declaration is implicitly extern, meaning it might be defined later in this file or to be found later when linking is performed.

a7

That's what "in a different translation unit" means (it's a different file being compiled separately, not to be confused with ino files which are concatenated together and compiled as a single translation unit during the Arduino build process).

Right, it's the entity that's eventually handed to the compiler. It consists of the source file, all files that get #include(d) - directly or indirectly, resolution of conditional compilation directives, the evaluation of all preprocessor macros, etc.

THX. Clearer now. Looks like I am forgetting how to read after all these years.

I also forget the part where all the *.ino files are just a single translation unit, which always seems odd.

Just another way that help is provided…

a7

When the regular C/C++ Compiler (like Code::Blocks) does not allow calling a user-defined function without having its prototype before the main() function, then the Arduino IDE's Compiler should have the same tendency. Am I correct?

However, the Arduino users are not strictly required to declare such prototypes as the compiler does it for them in the background, which I have understood reading various posts of this Forum. And yet some of the IDE's built-in functions like: Wire.onReceive(receiveEvent); and others do require forward declaration.

The Arduino compiler is a "Regular" C++ compiler. The difference is the preprocessing invoked by the Arduino IDE before the result is handed to the compiler. This has already been pointed out several times in this thread.

When you verify (or upload) a sketch, one of the first things that happens is that a program called arduino-builder is called; this is (possibly amongst other things) responsible for the generating of prototypes.

Your sketch

const byte ledPin = LED_BUILTIN;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blink();
}

void blink()
{
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
}

File that is actually compiled

#include <Arduino.h>
#line 1 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
#line 1 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
const byte ledPin = LED_BUILTIN;

#line 3 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
void setup();
#line 9 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
void loop();
#line 14 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
void blink();
#line 3 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_430523\\sketch_apr28a.ino"
void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blink();
}

void blink()
{
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
}

In more complicated programs, the arduino-builder however can drop a stitch in which case compiling will fail and you have to add e.g. the prototype yourself. This is e.g. the case with (global) function pointers.

Your sketch

const byte ledPin = LED_BUILTIN;

void (*DoBlink)() = blink;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blink();
}

void blink()
{
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
}

File that is actually compiled

#include <Arduino.h>
#line 1 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
#line 1 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
const byte ledPin = LED_BUILTIN;

void (*DoBlink)() = blink;

#line 5 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
void setup();
#line 11 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
void loop();
#line 16 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
void blink();
#line 5 "C:\\Users\\Wim\\AppData\\Local\\Temp\\arduino_modified_sketch_565224\\sketch_apr29a.ino"
void setup()
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  blink();
}

void blink()
{
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
}

The function prototype is placed after the declaration of the function pointer and hence you get an error that the compiler does not khow about blink . Adding the function prototype (or definition) before the function pointer declaration yourself solves the problem.

Practically, pupils in the classroom ask for the prototypes before the setup() function to comply with the rule that a variable/function must be declared before it is used/defined.

In your sketch of post #38, the user-defined function blink(); works well even without explicit forward declaration/prototype. However, your elegant presentation/analysis shows that the prototype is indeed created implicitly by the Arduino-builder. Good source to satisfy the thirsts of the pupils.

No it’s not even a language. It’s C++ with tool chains and specific options and libraries that you can use to abstract some hardware features of the bords