Hi all,
I think there's a bug which prevent the correct behaviour for the procedure parameters in the qb mode, where byval/byref have default handling for scalar/vector variables. Please consider in the file parser-decl-proc-params.bas the following excerpts:
273 '' (BYVAL|BYREF)?
274 select case lexGetToken( )
275 case FB_TK_BYVAL
276 mode = FB_PARAMMODE_BYVAL
277 lexSkipToken( )
278 case FB_TK_BYREF
279 mode = FB_PARAMMODE_BYREF
280 lexSkipToken( )
281 case else
282 mode = INVALID
283 end select
[..]
353 use_default = FALSE
354 if( mode = INVALID ) then
355 mode = env.opt.parammode
356 use_default = TRUE
357 if( fbPdCheckIsSet( FB_PDCHECK_PARAMMODE ) ) then
358 hParamWarning( proc, id, FB_WARNINGMSG_NOEXPLICITPARAMMODE )
359 end if
360 end if
[..]
406 '' in lang FB,
407 if( fbLangIsSet( FB_LANG_FB ) ) then
408
409 '' we have to delay the true default until now, since
410 '' byval/byref depends on the symbol type
411 if( use_default ) then
412 mode = symbGetDefaultCallConv( typeGet( dtype ), subtype )
413 end if
414
415 end if
In light of that IMO lines 406-407 should be changed in
406 '' in lang QB,
407 if( fbLangIsSet( FB_LANG_QB ) ) then
I tested with an old chess program (minimax), after recompilation it works fine.
Greetings, Marco Borsari.
I think it's correct as-is. fbc -lang qb and fbc -lang fblite will use ByRef for everything by default, only the default fbc -lang fb uses ByRef/ByVal default depending on the parameter data type. I tested under QuickBASIC 4.5 and QBasic 1.1, and they seem to pass all ByRef by default, so FreeBASIC's -lang qb seems to be correct there.
I found this gotcha though:
DECLARE SUB foo (i AS INTEGER)
DIM i AS INTEGER
'' In QB, this is passing (i) to a ByRef param, i.e. it's making an implicit copy
'' due to the parentheses, and the variable i won't be modified
'' In FB, the parentheses don't have an effect, and i will be modified
foo (i)
PRINT i
SUB foo (i AS INTEGER)
i = 5
END SUB
in QB this prints 0, while in FB -lang qb it prints 5, because of the difference in handling of parentheses. There is a to-do-list entry about this issue, but I'm not sure how much of a problem it is. Maybe your program is affected by this bug/unimplemented feature?
To test by myself I used a similar example, I read now in the documentation of quickbasic when a sub is previous declared it could be invoked without the call token, and one should be omitting the parenthesis. The reason is otherwise the parameter wiil be byval, I am sorry, that behaviour left me a little confused. In the minimax program I see sometimes there's a double nested parenthesis, to obtain the same effect. So you are right, thank you for clarification.