Declaration of Functions

So after an error Function was not defined in this scope or something like that.

So which way is better, to move the whole function ahead of "Setup" or just do the following at the top?

void Function1 ();

void Function2() {
  //Do Something
}

void Setup() {
  //Do Something
}
void loop() {
  //Do Something
}
void Function1() {
  //Do Something
}

Both resolved the error message, although I was able to move it back and delete these and I didn't get the error again. Is it something that should be done, and just isn't that critical or am I missing something?

Up to you however you want to mix 'em up.

-jim lee

I just find it odd how every once in a great while I will get the error and rest of the time I don't. Is there something that says we should and the IDE just picks and chooses when it decides to feel touchy or is there something else that is driving this?

Stupidav: So after an error Function was not defined in this scope or something like that.

Sometimes that means "There is an error in your sketch, after this point but before the 'not defined' function, that caused the 'not defined' function declaration to fail. Looking at the other error messages in the message box below the sketch may allow you to find the original error. In other words: sometimes the line that gets highlighted is NOT the location of the original error, just another symptom.

It is a special feature of the Arduino IDE that you can define functions after the point at which they are used without needing an explicit function prototype before hand. The Arduino build routine creates these prototypes but, unhappily, not always correctly, leading to errors which are not obvious. This is especially so if the function argument list contains user defined data types and the automatically created function prototype is placed before the declaration of that data type.

If you always define your own function prototypes, the IDE's auto-prototype feature will never cause you problems. And, you won't be caught by surprise when you more up to a more full-featured IDE that does not include this crutch.

Stupidav: I just find it odd how every once in a great while I will get the error and rest of the time I don't. Is there something that says we should and the IDE just picks and chooses when it decides to feel touchy or is there something else that is driving this?

I've been programming on Arduino's for three plus years and I have only had one instance of the IDE-generated function declarations failing.

Some people do their own declarations because that's the C/C++ way. If you want to do this, put all of the declarations into a separate .h file and put #include "myDeclarations" at the top of the sketch. It keeps the sketch cleaner.

It's also a form of self-documentation. You get to see right at the start, a list of the functions that you will encounter later in the code (in the form of function declarations). It allows you to place the function definitions in any order you like, which allows you to pick the most readable, logical order.

SteveMann: I've been programming on Arduino's for three plus years and I have only had one instance of the IDE-generated function declarations failing. . . .

One instance, that is one instance of a one or two day debugging session, is enough and then you learn. I did actually once report an example of this behavior having seen outbursts of frustration from experienced developers having been caught by this: https://github.com/arduino/arduino-builder/issues/362 . It is easier to explain that it is a bug in a feature rather than to try to explain the rationale behind it.

Yes, you can prevent this unwanted behavior by declaring your own (possibly otherwise unnecessary) prototypes, but you still have to know that the argument list on the prototype has to be an exact copy of that of the function definition. This is stricter than C++ which does not even require the variable names, only their data types, in the function prototype.

you still have to know that the argument list on the prototype has to be an exact copy of that of the function definition. This is stricter than C++ which does not even require the variable names, only their data types, in the function prototype.

The IDE seems quite happy with this. Note that the function prototype has no variable names

void functionA(byte, int);

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  functionA(123, 5678);
}

void loop()
{
}

void functionA(byte value1, int value2)
{
  Serial.print(value1);
  Serial.print("\t");
  Serial.println(value2);
}

UKHeliBob:
The IDE seems quite happy with this. Note that the function prototype has no variable names

That is not exactly the point I am making. In general, having function prototypes without variable names is of course fine. It is only that such function prototypes do not suppress the unwanted auto creation of prototypes.

In the example below are 2 alternative function prototypes, marked with a comment.
It fails if both prototypes are commented out
It fails if the prototype without variable names is active.
It succeeds if the prototype which exactly matches the function argument list is active.

//1.8.13
void functionA(byte, int);

void functionA(byte value1, int value2)
{
  Serial.print(value1);
  Serial.print("\t");
  Serial.println(value2);
}


enum class StateB{ one, two, three } ; 

   void functionB(StateB , int ) ;             //<< Prototype VALID  but fails
// void functionB(StateB value1, int value2) ;    //<< Prototype EXACT MATCH works 

void functionB(StateB value1, int value2)
{
  Serial.print( (int) value1);
  Serial.print("\t");
  Serial.println(value2);
}



void setup()
{
  Serial.begin(115200);
  while (!Serial);
  functionB( StateB::one, 5678);
}

void loop()
{
}

Thanks for the fuller explanation of what you meant

Your code, as posted, does indeed fail to compile

Arduino: 1.8.13 (Windows 10), Board: "Arduino Nano, ATmega328P"

sketch_dec16a:18:16: error: variable or field 'functionB' declared void

 void functionB(StateB value1, int value2)

                ^~~~~~

sketch_dec16a:18:16: error: 'StateB' was not declared in this scope

C:\Users\Bob2\AppData\Local\Temp\arduino_modified_sketch_182052\sketch_dec16a.ino:18:16: note: suggested alternative: 'static'

 void functionB(StateB value1, int value2)

                ^~~~~~

                static

sketch_dec16a:18:31: error: expected primary-expression before 'int'

 void functionB(StateB value1, int value2)

                               ^~~

exit status 1

variable or field 'functionB' declared void



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

but curiously, moving functionA() to the end of the sketch

//1.8.13
void functionA(byte, int);

enum class StateB { one, two, three } ;

void functionB(StateB , int ) ;             //<< Prototype VALID  but fails
// void functionB(StateB value1, int value2) ;    //<< Prototype EXACT MATCH works

void functionB(StateB value1, int value2)
{
  Serial.print( (int) value1);
  Serial.print("\t");
  Serial.println(value2);
}



void setup()
{
  Serial.begin(115200);
  while (!Serial);
  functionB( StateB::one, 5678);
}

void loop()
{
}


void functionA(byte value1, int value2)
{
  Serial.print(value1);
  Serial.print("\t");
  Serial.println(value2);
}

allows it to compile OK with no complaints about functionB()

If you put your global declarations at the top, the automatic prototypes work:

//1.8.13
enum class StateB { one, two, three } ;


void setup()
{
  Serial.begin(115200);
  while (!Serial);
  functionB( StateB::one, 5678);
}


void loop()
{
}


void functionA(byte value1, int value2)
{
  Serial.print(value1);
  Serial.print("\t");
  Serial.println(value2);
}


void functionB(StateB value1, int value2)
{
  Serial.print( (int) value1);
  Serial.print("\t");
  Serial.println(value2);
}

Automatic prototypes are emitted just before the first function. If the prototype uses a variable type (class, enum, struct, union, typedef) that is not defined above that point, the prototype will generally cause an error.

Always put your enum/struct/union/class/typedef declarations before the first function.

If you put your global declarations at the top, the automatic prototypes work:

Thanks John. That is a very interesting observation

Hello, There is a function declaration and function definition in c or c++. Usually you declare a function at the beginning of your code, for easy reading before setup() with the variables declarations. And you define the function after the main loop. These are agreed c good practices on writing code.

abdelhmimas: Usually you declare a function at the beginning of your code, for easy reading before setup() with the variables declarations.

It's a matter of programming style. C and C++ do not require function prototypes (forward declarations) unless the function is used before it is defined. Some organizations may implement a style standard that requires them for all functions, but that is just a style. Arduino tries to generate them automatically for you and that can cause confusion if the automatic prototypes fail in some way.

abdelhmimas: And you define the function after the main loop.

That is another aspect of programming style.

abdelhmimas: These are agreed c good practices on writing code.

Not everyone agrees that that style is better than every other style. Everyone should use the style that works best for them (or their employer).

I've updated the case I opened here , regarding the prototype building issue, to a link to this thread in case it helps with the development of any solution.

The Arduino Builder functionality is now incorporated in Arduino CLI so I guess it has the same issues.