5.10 Forward Procedures


5.10 Forward Procedures

As a general rule HLA requires that you declare all symbols before their first use in a program.[11] Therefore, you must define all procedures before their first call. There are two reasons this isn't always practical: mutual recursion (two procedures call each other) and source code organization (you prefer to place a procedure in your code after the point you've first called it). Fortunately, HLA lets you use a forward procedure definition to declare a procedure prototype. Forward declarations let you define a procedure before you actually supply the code for that procedure.

A forward procedure declaration is a familiar procedure declaration that uses the reserved word @forward in place of the procedure's declaration section and body. The following is a forward declaration for the quicksort procedure appearing in the last section:

 procedure quicksort( var a:ArrayType; Low:int32; High: int32 ); @forward; 

A forward declaration in an HLA program is a promise to the compiler that the actual procedure declaration will appear, exactly as stated in the forward declaration, at a later point in the source code. "Exactly as stated" means exactly that. The forward declaration must have the same parameters, they must be passed the same way, and they must all have the same types as the formal parameters in the procedure.[12]

Routines that are mutually recursive (that is, procedure A calls procedure B, and procedure B calls procedure A) require at least one forward declaration because you may only declare one of procedure A or B before the other. In practice, however, mutual recursion (direct or indirect) doesn't occur very frequently, so the need for forward declarations is not that great.

In the absence of mutual recursion, it is always possible to organize your source code so that each procedure declaration appears before its first invocation. What's possible and what's desired are two different things, however. You might want to group a related set of procedures at the beginning of your source code and a different set of procedures toward the end of your source code. This logical grouping, by function rather than by invocation, may make your programs much easier to read and understand. However, this organization may also yield code that attempts to call a procedure before its declaration. No sweat. Just use a forward procedure definition to resolve the problem.

One major difference between the forward definition and the actual procedure declaration has to do with the procedure options. Some options, like @returns may appear only in the forward declaration (if a @forward declaration is present). Other options may only appear in the actual procedure declaration (we haven't covered any of the other procedure options yet, so don't worry about them just yet). If your procedure requires a @returns option, the @returns option must appear before the @forward reserved word. For example:

 procedure IsItReady( valueToTest: dword ); @returns( "EAX" ); @forward; 

The @returns option must not also appear in the actual procedure declaration later in your source file.

[11]There are a few minor exceptions to this rule, but it is certainly true for procedure calls.

[12]Actually, "exactly" is too strong a word. You will see some exceptions in a moment.




The Art of Assembly Language
The Art of Assembly Language
ISBN: 1593272073
EAN: 2147483647
Year: 2005
Pages: 246
Authors: Randall Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net