PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: FreeBasic Try-Catch-Throw feature  (Read 318 times)

Marc Pons

  • FireFly3 Registered User
  • Junior FireFly Member
  • *
  • Posts: 110
  • FF3 User
FreeBasic Try-Catch-Throw feature
« on: December 07, 2017, 05:07:55 AM »

Hi, all

I'm pleased to post here my new piece of code : Try-Catch-Throw for Freebasic (32 & 64)

During the last months I was mainly playing with c c++ and java  ( doing projects from the free school  Ecole42)
and experiencing the exceptions on c++ and java was very confortable
In c it does not exist natively so i decide to mimic that feature on plain c as an exercice :
 in mingw gcc it exists  some extensions ( _try1 / _expect1) using asm macros , but not totally implemented
but also setjmp/longjmp to make jumps to specific area code position, most of the c proposed solutions on the net are using these functions
so i made my own implementation , incorporation the signal interruptions to make a "good" solution to c.

Back to FreeBasic i tried to implement a similar solution , using the same setjmp/longjmp
i have found it works easily on 32 but crashs on 64 ,  incomplete header implementation for windows platform (works in linux)
with some advice and tweak i made it working also for 64

the other point to have a complete exception management is to collect the "normal" system errors
to be able to have a good normal terminaison even in critical situations
that point on FreeBasic windows is not easy, it does not work correcly via the signal (Posix) functions
we can catch some but most of the crash situation are difficult to intercept via signal handing
but in windows it exists other mechanisms , the most interesting almost commun to 32 & 64 is "VectoredException"
after some hours i was able to collect the main critical situations so, that the preferable way.

You should note, FreeBasic compiler, is very well "protected" ,
difficult to have segfault because the memory management is very strong
and by the way is very tolerant to faults,
 same for overflow/underflow in numbers , and even for array bounds

to finish the story, that implementation is able to work on infinite nested Try-Catch-Finally-EndTry blocks  (Finally is optionnal)

I'm sure , (and it is why i post it) with the talented guys here, it will be extended, simplified corrected...  to be even more reliable.

I count specialy on Josť , Paul , who are doing an enormous step forward for Freebasic ( on windows side)
i'm quite sure, that inforced feature could give some benefit on your current development...

Feel free to test, modify , ask whatever you want


the attached file is put as a complete test file, it would easily be declined as .inc file...

i put it in zip file because  the .bas file was strangly rejected

Marc Pons

  • FireFly3 Registered User
  • Junior FireFly Member
  • *
  • Posts: 110
  • FF3 User
Re: FreeBasic Try-Catch-Throw feature
« Reply #1 on: December 09, 2017, 03:44:25 PM »

New version using class  and no more global shared vars 

1 function with only a static var

new feature rethrow   ( to collect at  level -1)

limited as 64 levels ( but be changeble via define)

could also be unlimited with a linked list (but with array is faster)
tried also alloc /realloc but carefull , the pointer of the array change....  so segfault immediatly


Marc Pons

  • FireFly3 Registered User
  • Junior FireFly Member
  • *
  • Posts: 110
  • FF3 User
Re: FreeBasic Try-Catch-Throw feature
« Reply #2 on: December 11, 2017, 11:14:23 AM »

Again with new version

this time it is an include file + a test file

the class has been modified (using static members ) simplifying the management
and give the opportunity to have unlimited levels of try-catch  by increasing the memory by steps
the pointers are not lost because the static members are like globals they will hold the value and we can read/write from everywhere

i use a "sort" of simplified singleton protected by Static countID to avoid the class been instancied more than 1 time

the include file has 2 parts the top is the common part (like a .bi file) used to declare only
the second part protected by   # ifdef _EXCEPTIONS_INIT_CODE_    is the definition body for class and functions/subs

if you use single .bas file compilation (as in powerbasic)
        main.bas file  and included .inc files ;
        put the  # define _EXCEPTIONS_INIT_CODE_  before the  #include once "" in that main.bas file
        the example is like that

if you use multiple modules .bas files (compiled  to .o files) as c is used to do
        each of the .bas file using the exception management needs the  #include once ""
       and the "main.bas"  will have the # define _EXCEPTIONS_INIT_CODE_  before the  #include once ""

doing like that, it prevents the multiple definition error at compile time
and initialises the class to catch the exceptions even before the first TRY in the code.

I hope that implementation will interress somebody ...
do not hesitate to react.



Marc Pons

  • FireFly3 Registered User
  • Junior FireFly Member
  • *
  • Posts: 110
  • FF3 User
Re: FreeBasic Try-Catch-Throw feature
« Reply #3 on: December 15, 2017, 01:10:35 PM »

noticed someting missing  : not freeing the memory when reallocating

please change the method code   : Private sub my_except_class.increase_except()

Code: [Select]
Private sub my_except_class.increase_except()
if my_except_class.e_pos + 1 = e_size  THEN
dim as exdata_type Ptr ptemp2 = callocate(sizeof(exdata_type) * e_size * 2)
if ptemp2 = 0 THEN
messagebox 0, "Close to abort !", "error .... reallocating", MB_ICONERROR
memmove(ptemp2, my_except_class.e_data, sizeof(exdata_type) * e_size)
deallocate(my_except_class.e_data)      ' here to free the memory!!!!!!!
                        end if
my_except_class.e_data = ptemp2
e_size *= 2
if VERBOSE then print "reallocating... done"
end if
my_except_class.e_pos += 1
my_except_class.e_data[my_except_class.e_pos].jump = new jmp_buf
my_except_class.e_data[my_except_class.e_pos].h1 = AddVectoredExceptionHandler(my_except_class.e_pos , @Intercept_Exceptions)
my_except_class.e_data[my_except_class.e_pos].icod = 0
my_except_class.e_data[my_except_class.e_pos].got = 0
my_except_class.e_data[my_except_class.e_pos].file = ""
my_except_class.e_data[my_except_class.e_pos].proc = ""
my_except_class.e_data[my_except_class.e_pos].msg = ""
my_except_class.e_data[my_except_class.e_pos].line = 0
end sub