I'm using the meta-command #INCLUDE verry often to get a good structure of my tools during programming with freebasic. And I'm using a lot of self-made-code to test my tools.
The structure got more and more complex and it started to get more and more errors during compiling and they made me wondering, because this errors were not the reason of my problems!
I've found out, that if I start my coding with v.e. main.bas and I take v.e. 2 module-files I named them sub1.bas and sub2.bas and if I include (for some reason) in one of the included files like:
#INCLUDE ONCE main.bas
... I get the error:
main.bas(9) error 4: Duplicated definition, foo in 'Dim foo As String'
that is, because main.bas is executed 2 times !
1st time at start
2nd time at #INCLUDE ONCE main.bas (please look to sub2.bas)
Solution could be: the starting-file should be put on the list of included files as well at start to avoid the 2nd use of that code.
Thank You for help.
main.bas
#Print Compiling the module main.bas ' ' main.bas ' #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub1.bas" #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub2.bas" ' ' Dim foo As String ' Print "test done" Sleep 3000 ' '
sub1.bas
' #Print Compiling the module sub1.bas ' ' sub1.bas ' #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub1.bas" #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub2.bas" ' ' Print "sub1 done" '
sub2.bas
' #Print Compiling the module sub2.bas ' ' sub2.bas ' #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub1.bas" #Include Once "C:\Program Files\freeBASIC\freeBASIC\sub2.bas" ' ' v-------- this "Once" is NOT working correct for the 1st top main-program main.bas #Include Once "C:\Program Files\freeBASIC\freeBASIC\main.bas" ' Print "sub2 done" '
result:
without the line {#Include Once "main.bas"} at file sub2.bas
sub2 done sub1 done test done
compile-log:
C:\Program Files\freeBASIC\freeBASIC\fbc -s gui -showincludes "main.bas" main.bas Compiling the module main.bas | sub1.bas Compiling the module sub1.bas | | (sub1.bas) | | sub2.bas Compiling the module sub2.bas | | | (sub1.bas) | | | (sub2.bas) | | | main.bas Compiling the main.bas | | | | (sub1.bas) | | | | (sub2.bas) | (sub2.bas) main.bas(9) error 4: Duplicated definition, foo in 'Dim foo As String' Build error(s)
In your example the expression '#Include Once "C:\Program Files\freeBASIC\freeBASIC\sub1.bas"' is encountered multiple times so only one include expression is kept.
Likewise for 'sub2.bas'.
But for 'main.bas', a single expression '#Include Once "C:\Program Files\freeBASIC\freeBASIC\main.bas"' is encountered, so it is kept, which explains the double declaration of 'foo'.
thank You for that fast answer ...
but what You'r explaining are facts that are known and I know.
My exaples are only a short explanation of the problem.
Did You understood the problem?
I dont know how to call the first file. Start-code-file, "grand-grand-grand....-father"-file or the "first"-file which ist the begin of whole code.
This start-file should be put on the list of included file by compiler. To be sure, in which case ever, never be included a 2nd time! Otherwise a lot of implementations have same troubles whith this inconsistency (I think a lot of problems at forum are caused by this, because error-message are verry confusing)
...
Last edit: LordMaserati 2021-02-22
One easy thing you can do help keep organized with the structure of your program is to:
- use a
.bas
filename extension for files that get compiled (the files listed on the fbc command line)- use a
.bi
filename extension for files that get included.Maybe have a look at:
-Source Files
-Header Files
Here's some really simple example programs to highlight the current behaviours of
#include once
and#pragma once
.PROGRAM 1 (#include once):
Relative Path:
Absolute Path:
PROGRAM 2 (#pragma once, #include):
Relative Path:
Absolute Path:
From the examples can see that we get slightly different behaviour between on
#pragma once
depending on if a relative or absolute path was used.I would expect the same behaviour for
#pragma once
in either case. And I suspect that fixing the#pragma once
bug should fix the#include once
bug. But I also suspect that will have to follow the filename usage through fbc. There's many places where fbc uses the relative filename only and to have fbc solve the relative path with an absolute path up front is going to change a lot of output that fbc generates.It's probably OK to have fbc have all files on the command line automatically be added as
#include once
files. I think it would be an unusual case for a main.bas level source file to include itself, however that could also be a tricky way to have the compiler make exactly a second pass only a source file; maybe first pass to set-up some#defines
and a second pass to generate code. But that seems far fetched. But if that was the behaviour, then at least#pragma once
should be made to work consistently