Tabs in Arduino IDE

Default parameters are specified in the function prototype but from memory the function prototype must precede the use of the function in the code due to how the Arduino IDE works

Try this. It does not compile

void setup() { Serial.begin(115200); funcA(); } void loop() { } void funcA(int X = 1) { Serial.println(X + 1); }

but this does

void funcA(int X = 1); void setup() { Serial.begin(115200); funcA(); } void loop() { } void funcA(int X = 1) { Serial.println(X + 1); }

Now, if the function is declared in another tab then it will not be before it is used in the main .ino so compilation fails

This is interesting. I frequently put my functions into tabs and never have to declare them before they are called.

This compiles:

void setup() { Serial.begin(115200); funcA(1); } void loop() { } void funcA(int x) { Serial.println(x + 1); } 

And placing funcA into a tab also compiles.

But, defining a default argument:
void funcA(int X = 1)
Will not compile without declaring the function.

I've gotten comfortable with letting the compiler do my declarations for me.

Gfvalvo, you like to use .h and .cpp instead of putting functions into .ino files- how would you code this example in a .h and .cpp file?

looks like the definition doesn't need to specify the default, only the declaration needs to.

void funcA (int X = 1); void setup () { Serial.begin (115200); funcA (); } void loop () { } void funcA (int X) { Serial.println (X + 1); } 

Of course. It makes sense when you think about it a little. This allows the declaration to be separated into a .h file. That's the function's "interface". It's all the compiler needs to compile another file that calls that function.

So, the "another file" #include(s) the .h file. Now, when that file is compiled, the compiler checks to see if the function call includes all the arguments. If not, it substitutes the default ones (there are certain rules though). This allows the file to compile without error.

Now, when the linker stitches everything together, the function will always be called with a full complement of arguments.

The automatically generated function declarations for all .ino files are added near the top of the primary sketch file. So being in a tab has no effect on the situation with declarations.

This issue is specific to functions that have default values. The Arduino sketch preprocessor does not generate declarations for functions with default parameter values.

Given this sketch UKHeliBob shared:

the preprocessed code looks like this:

#include <Arduino.h> #line 1 "C:\\Users\\per\\Documents\\Arduino\\default\\default.ino" #line 1 "C:\\Users\\per\\Documents\\Arduino\\default\\default.ino" void setup(); #line 7 "C:\\Users\\per\\Documents\\Arduino\\default\\default.ino" void loop(); #line 1 "C:\\Users\\per\\Documents\\Arduino\\default\\default.ino" void setup() { Serial.begin(115200); funcA(); } void loop() { } void funcA(int X = 1) { Serial.println(X + 1); } 

Notice that declarations were generated for the setup and loop functions, but not for funcA.

So why does the preprocessor skip this sort of function? You can get the answer by compiling UKHeliBob's second sketch with compiler warnings turned on:

C:\Users\per\Documents\Arduino\default\default.ino: In function 'void funcA(int)': C:\Users\per\Documents\Arduino\default\default.ino:12:21: warning: default argument given for parameter 1 of 'void funcA(int)' [-fpermissive] void funcA(int X = 1) ^ C:\Users\per\Documents\Arduino\default\default.ino:1:6: note: previous specification in 'void funcA(int)' here void funcA(int X = 1); ^~~~~ 

This is a only a warning, but that is because I compiled for a board of the Arduino AVR Boards platform, which (somewhat controversially) uses the -fpermissive compiler flag, downgrading some compiler errors to warnings. If you compile the same sketch with one of the other common platforms like Arduino SAMD Boards that don't use -fpermissive, it becomes an error:

C:\Users\per\Documents\Arduino\default\default.ino: In function 'void funcA(int)': default:12:21: error: default argument given for parameter 1 of 'void funcA(int)' [-fpermissive] void funcA(int X = 1) ^ C:\Users\per\Documents\Arduino\default\default.ino:1:6: note: previous specification in 'void funcA(int)' here void funcA(int X = 1); ^~~~~ 

So the only way the preprocessor could correctly generate declarations for functions with default parameter values would be to actually modify the function definition to remove them. The scope of sketch modifications during preprocessing has always been limited to only adding lines to the sketch. It has never modified the user's lines (or if it did then only due to a bug in the preprocessor). In addition to being quite intrusive, it would likely be quite difficult to do this in a manner that would work for every edge case.

The current approach is that the user is expected to provide their own function declaration if they need default parameter values. It does come up from time to time, but probably once or twice a year at most. I'm not sure whether it's because people writing .ino Arduino don't often use default parameter values (they might not even know about it since it's not mentioned in the Arduino Language reference, and the fact that the Arduino language is a superset of C++ is not well advertised either) or if it's fairly intuitive to add the declaration since it's unusual to specify default values in the function definition even in C++.

That neatly summarises the requirement and I have quoted it here to emphasise it

Normally, you would have:

// tab2.ino (for instance) void anotherfunction(char colour = 'r', byte Flash=255) { //some action } 
// main sketch tab void loop { anotherfunction( 'g', 255); } 

You should probably note that 'RE' is NOT a "char"...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.