PRIVATE_BEGIN and _END

Updated August 2018; see History

++PRAGMA PRIVATE_BEGIN

   <map and dimx statements>

++PRAGMA PRIVATE_END

This set of pragmas may be used within ++INCLUDE files to ensure that the module's private variables (MAP and DIMX) are initialized once and only once before they are used, regardless of the position of the ++INCLUDE in the main program. Previously, without the benefit of the new pragmas, it was left to the programmer to make sure that any such MAP statements containing initializers, and any DIMX statements, got executed, just once, before being used. Typically that required that the ++INCLUDE be at the top of the main program, so that execution fell through the MAP and DIMX statements before the main program started executing, or it required a static control variable and some conditional logic within the ++INCLUDE module to keep track of whether the initializations had occurred.

Using these pragmas, the compiler takes care of the problem, making sure that the enclosed MAP and DIMX statements are initialized before any of the functions or procedures within the module are executed.

Secondarily, as a syntactic convenience, the keyword PRIVATE will be automatically added to any MAP or DIMX statement enclosed by the pragmas if not already explicitly specified. Thus, if you really do want to specify global variables within such a ++INCLUDE module, you must keep then outside the set of pragmas lest they be turned into module private variables.

Notes

•   Each ++INCLUDE module can have only a single pair of these pragmas

•   The feature is entirely implemented in the compiler, so there is no requirement for a corresponding update of the runtime system.

•   Other kinds of statements may be included within the PRIVATE_BEGIN and _END pragmas, such as assignments or function calls related to initializing the private variables. As with the MAP and DIMX statements, they would be guaranteed to execute prior to any of the functions or procedures within the module, and only once.

Example

! (main program)

...

if Fn'GetTableItem$(X) = "" then

    call SetTableItem(X, "Behold!")

endif

...

++include table.bsi

 

- - - - - - - - -

 

! (table.bsi)

 

++pragma private_begin

map1 table'max,f,6,5000

dimx table(table'max),s,100

++pragma private_end

...

Function Fn'GetTableItem$(idx as f) as s100

   if (idx <= table'max) then Fn'GetTableItem$ = table(idx)

EndFunction

 

Procedure SetTableItem(idx as f, item$ as s100)

   if (idx <= table'max) then table(idx) = item$

EndProcedure

 

In the above example, the module table.bsi contains a private DIMX array table() which is shared by the function and procedure in the module. Because the module is included at the bottom of the main program, without the ++pragma private_begin, the array would still be unitialized at the point it was referenced in the Fn'GetTableItem$() function, leading to an error. To correct for that, the ++INCLUDE statement would have to be moved to the top of the main program, but that is an undesirable dependency which the programmer creating the table.bsi would rather not have to depend on. And it is otherwise not easy to code around the problem. But with the ++pragma private_begin, the problem disappears.

History

2018 August, A-Shell 6.5.1641, compiler edit 868:  Language enhancement: PRIVATE variables and ++PRAGMA PRIVATE_BEGIN / _END blocks may now be used in the main source module to limit the scope of those variables to just that source file. Note that this enhancement entirely handled by the compiler; there is no issue with backwards or forwards runtime compatibility, even under AMOS.

2016 November, A-Shell 6.3.1534, compiler edit 790:  use of .ARGCNT within a PRIVATE_BEGIN / PRIVATE_END block now generates a compile error. Although the expression wouldn't technically be illegal, because the PRIVATE block is essentially called for initialization by whatever function or procedure in the module gets called first, there's really no good way to predict in advance what the .ARGCNT value will represent, and thus it is almost certain to create a discrepancy between the expected and actual behavior.

2013 February, A-Shell 6.1.1338:  Pragmas added to A-Shell, compiler edit 624.