flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [fasmg] Protection against duplicated includes

Author
Thread Post new topic Reply to topic
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 04 Jan 2026, 01:46
There's one question I still have not figured out how to deal with, it is the classical duplicate include protection (a.k.a. 'include guard'), that issues an error when the same file (for any reason) gets included more than once.

In C, it seems like (I'm not good in C, so, don't judge me Laughing ):

Code:
#ifndef __SOME_UNIQUE_NAME__
#define __SOME_UNIQUE_NAME__
// do stuff
#else
#error Duplicated inclusion of <file>
#endif
    


If I try to do something similar using fasmg language, it ends in a "recursion loop" (I suppose), and doesn't end being compiled:

Code:
if ~ defined __F_INCLUDE_FILE_INCLUDED__
        define __F_INCLUDE_FILE_INCLUDED__
else
        err "Duplicated inclusion of file ", __FILE__, 10
end if
    


Quote:

flat assembler version g.l04h
Error: could not generate code within the allowed number of passes.
[ble: exit 2]


However, by doing the following, it actually works:

Code:
if ~ defined __F_INCLUDE_FILE_INCLUDED__
        define __F_INCLUDE_FILE_INCLUDED__
else
        err "Duplicated inclusion of file ", __FILE__, 10
end if

__F_INCLUDE_FILE_INCLUDED__ = 0   ; disabling this line makes fasmg go brrrrrrrrr...
    


Quote:

flat assembler version g.l04h
incldef.asm [3] f_include.inc [4]
Custom error: Duplicated inclusion of file f_include.inc
.


I know in anticipation that fasmg kind of look ahead (by its several passes), and this probably have to do with the previous model not working.
But I can't understand why the second one works.

So, I ask: is there a better fasmg way of doing such a thing?

Thanks in advance,

_________________
jesse6
Post 04 Jan 2026, 01:46
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4342
Location: vpcmpistri
bitRAKE 04 Jan 2026, 07:21
This might work for your use-case:
Code:
; We can make a global "#pragma once" mechanism if we assume all files have
; a unique path. Non-cannonical paths are fine as long as it's always the same
; form. Be mindful of file organization if you're going to use this.
; Primary benefits:
;       + files are not loaded multiple times
;       + no change to file needed (i.e. if/endif wrapper)

calminstruction onetime?: line*&
        match name any?,line
        jyes go
        err 'filename expected'
done:   exit

        local val,var
go:     compute val,+name               ; convert string to number
        arrange var,=ONETIME.val        ; unique variable
        check definite var
        jyes done

        compute val,0
        publish var:,val                ; constant

        arrange line,=include line
        assemble line
end calminstruction    
Note: the consumer needs to know - which is a different policy than the product establishing the condition. If fasmg's __FILE__ always produced a canonicalized path then an ideal "#pragma once" would be possible. Maybe it should be called "module" to follow the C++ language changes?

_________________
¯\(°_o)/¯ AI may [not] have aided with the above reply.
Post 04 Jan 2026, 07:21
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4342
Location: vpcmpistri
bitRAKE 04 Jan 2026, 08:42
Jessé wrote:
But I can't understand why the second one works.
The trick is that forward references only work for "constants" (i.e. is only defined/set once). So, by setting the value more than once it becomes a "variable" and forward referencing is disabled for it.

_________________
¯\(°_o)/¯ AI may [not] have aided with the above reply.
Post 04 Jan 2026, 08:42
View user's profile Send private message Visit poster's website Reply with quote
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 04 Jan 2026, 12:37
Nice, I did other tests and now it become clear.
Simply doubling the define statement inside if block also work (because it "pushes" another definition to the symbol, making it a variable definition, I guess).
Which means my idea was not wrong, it just missing understanding how it works.

The calminstruction example looks very interesting.
I'll save it to test it further.
Post 04 Jan 2026, 12:37
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.