Use of TABs in the code

Using a Mac with macOS Big Sur 11.6 and Arduino IDE 1.8.16 or 1.8.19
I am on a project for home automation with weather measurements, a bit comprehensive.
Therefore I use the TABs provided by the IDE to get some order in the code.
And once in a while, when checking the code or uploading, I get an error message in the form :
'abc' was not declared in this scope.
It looks like "abc" is always a function that was declared in a TAB.
When the code of that function is inserted in the main TAB (the one that has the name of the enclosing folder, things work again, unless the IDE struggles with another function in a TAB.
Last time I could only escape by getting backups of the IDE, the folder "Arduino15" in the user lib and by rolling back to a former version of the code.
Then everything runs smooth again for some time.

Last time I got it was when I added some comments in a separate TAB that does not include anything else but a bunch of text enclosed by /* and */.
To avoid the problem is to regroup all the code in one single TAB (the main one), but that can hardly be intention of TABs.

Can anybody clarify a bit of how these TABs are handled and in what order they are processed by the compiling system, or give a link to some explanation?

Thanks in advance
Paul Colin

What is the file type, ie the extension, of the extra IDE tabs that you are using ?

The IDE stores them in the enclosing folder and all the extensions are ".ino"

I assume your tabs are all .ino extension?

in that case the IDE dump their content all together, in alphabetical order, into a huge .ino then tries to generate prototypes for the forward declaration of the functions and add them at the beginning and then compiles.

The challenge is that forward declaration identification fails sometimes and thus you end up breaking a C++ rule that states that something needs to be declared before you can use it...

One way to solve this is to provide yourself all the forward declaration. at the start of the sketch's main .ino

imagine you have those 3 functions in three different tabs

void func1(int x) {...}
void func2(char c) {...}
void func3() {...}

then add at the beginning of the main .ino

void func1(int x);
void func2(char c);
void func3();

ideally you would not depend on the IDE's non standard way of dealing with this and would create correct interface files (.h) and implementation files (.cpp) and use #include to import the relevant .h files where needed

I looked at the TABs in the TAB bar and it seems the ordered in alphabetically in upper case and then alphabetically the lower case. Not sure if the linker or compiler take this into account.
But I will give it a try with the sort of dummy function call as you suggest.
I will report on the result.

as said, the compiler / linker does not see the tabs, it see a temp file generated by the IDE where everything (all the .ino) have been merged

When I used tabs I have a single .ino "main" sketch and each tab is given a .cpp extension.

Each .cpp file is given its own .h file.

In each instance where I want a .cpp file-specific variable or function to be visible outside the scope of that .cpp file, I extern a prototype of it in the .h file and include that .h file wherever the reference is to be used.

Something to be careful of, if you leave an unpaired curly bracket ( {} ), quote mark, comment marks ( /* and */ ), etc, in a tab, then the compiler continues on with whatever is in the next tab it processes. That can lead to some difficult to find problem since the error/warnings tend to occur in a different tab that where the problem started.

Use the auto-format in the IDE and make sure all the tabs line up properly at the end.

For a more structured method of using multiple files / tabs, see My Reply #5 Here.

The only thing this doesn't cover (I think) is C++ Templates.

When adding a new TAB, things happen without the possibility of intervention.
In the enclosing folder, .ino files are created.
Is there a possibility to mange this?

What does that mean?

When you select New Tab and you're given the opportunity to name it, use the full name. If you name it "foo" then the file "foo.ino" will be created. But if you name it "foo.cpp" then the .ino extension will be replaced with .cpp.

Similarly, name your include file "foo.h".