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++.