4D v14.3Using Compiler Directives |
|||||||||||||||||||||||||||
|
4D v14.3
Using Compiler Directives
|
Boolean |
Fixed string |
Date |
Integer |
Longint |
Graph |
Time |
Picture |
Number (or Real) |
Pointer |
Text |
BLOB |
Object |
Here are the different types of arrays:
Boolean Array |
String Array |
Date Array |
Integer Array |
Longint Array |
Picture Array |
Real Array |
Time Array |
Object Array |
Pointer Array |
BLOB Array |
Text Array |
Notes:
- The "object" type is available starting with 4D v14.
- Since version 11 of 4D, there is no longer any difference between Alpha type variables and Text type variables. It is now recommended to use the Text type.
In interpreted mode, a variable can have more than one data type. This is possible because the code is interpreted rather than compiled. 4D interprets each statement separately and comprehends its context. When you work in a compiled environment, the situation is different. While interpretation is performed line by line, the compilation process looks at a database in its entirety.
The compiler's approach is the following:
If the compiler comes across the same variable name and two different data types, it has no reason to favor any particular one. In other words, in order to type an object and give it a memory address, the compiler must know the precise identity of that object (i.e., its name and its data type). The compiler determines its size from the data type. For every compiled database, the compiler creates a map that lists, for each variable, its name (or identifier), its location (or memory address), and the space it occupies (indicated by its data type). This map is called the symbol table. An option in the Preferences lets you choose whether to generate this table in the form of a file during compilation.
This map is also used for the automatic generation of compiler methods.
If you want the compiler to check the typing of your variables or to type them itself, it is easy to place a compiler directive for this purpose. You can choose between two different possibilities, depending on your working methods:
Compiler directives are useful in two cases:
Furthermore, using compiler directives allows you to reduce compilation time.
Sometimes the compiler cannot determine the data type of a variable. Whenever it cannot make a determination, the compiler generates an appropriate error message.
There are three major causes that prevent the compiler from determining the data type: multiple data types, ambiguity on a forced deduction and the inability to determine a data type.
Multiple data types
If a variable has been retyped in different statements in the database, the compiler generates an error that is easy to fix.
The compiler selects the first variable it encounters and arbitrarily assigns its data type to the next occurrence of the variable having the same name but a different data type.
Here is a simple example:
in method A,
Variable:=True
in method B,
Variable:="The moon is green"
If method A is compiled before method B, the compiler considers the statement Variable:="The moon is green" as a data type change in a previously encountered variable. The compiler notifies you that retyping has occurred. It generates an error for you to correct. In most cases, the problem can be fixed by renaming the second occurrence of the variable.
Ambiguity on a forced deduction
Sometimes, due to a sequence, the compiler can deduce that an object's type is not the proper type for it. In this case, you must explicitly type the variable with a compiler directive.
Here is an example using the default values for an active object:
In a form, you can assign default values for the following objects: combo boxes, pop-up menus, tab controls, drop-down lists, menu/drop-down lists and scrollable areas using the Edit button for the Value List (under the Entry Control theme of the Property List) (for more information, refer to the 4D Design Reference manual). The default values are automatically loaded into an array whose name is the same as the name of the object.
If the object is not used in a method, the compiler can deduce the type, without ambiguity, as a text array.
However, if a display initialization must be performed, the sequence could be:
Case of
:(Form event=On Load)
MyPopUp:=2
...
End case
In this case, the ambiguity appears––when parsing methods, the compiler will deduce a Real data type for the object MyPopUp. In this case, it is necessary to explicitly declare the array in the form method or in a compiler method:
Case of
:(Form event=On Load)
ARRAY TEXT(MyPopUp;2)
MyPopUp:=2
...
End case
Inability to determine a data type
This case can arise when a variable is used without having been declared, within a context that does not provide information about its data type. Here, only a compiler directive can guide the compiler.
This phenomenon occurs primarily within four contexts:
Pointers
A pointer cannot be expected to return a data type other than its own.
Consider the following sequence:
Var1:=5.2(1)
Pointer:=->Var1(2)
Var2:=Pointer->(3)
Although (2) defines the type of variable pointed to by Pointer, the type of Var2 is not determined. During compilation, the compiler can recognize a pointer, but it has no way of knowing what type of variable it is pointing to. Therefore it cannot deduce the data type of Var2. A compiler directive is needed, for example C_REAL(Var2).
Multi-syntax commands
When you use a variable associated with the function Year of, the variable can only be of the data type Date, considering the nature of this function. However, things are not always so simple. Here is an example:
The GET FIELD PROPERTIES command accepts two syntaxes:
GET FIELD PROPERTIES(tableNo;fieldNo;type;length;index)
GET FIELD PROPERTIES(fieldPointer;type;length;index)
When you use a multi-syntax command, the compiler cannot guess which syntax and parameters you have selected. You must use compiler directives to type variables passed to the command, if they are not typed according to their use elsewhere in the database.
Commands with optional parameters of different data types
When you use a command that contains several optional parameters of different data types, the compiler cannot determine which optional parameters have been used. Here is an example:
The GET LIST ITEM command accepts two optional parameters; the first as a Longint and the other as a Boolean.
The command can thus either be used as follows:
GET LIST ITEM(list;itemPos;itemRef;itemText;sublist;expanded)
or like this:
GET LIST ITEM(list;itemPos;itemRef;itemText;expanded)
You must use compiler directives to type optional variables passed to the command, if they are not typed according to their use elsewhere in the database.
Methods called via URLs
If you write 4D methods that need to be called via a URL, and if you do not use $1 in the method, you must explicitly declare the text variable $1 with the following sequence:
C_TEXT($1)
In fact, the compiler cannot determine that the 4D method will be called via a URL.
If all the variables used in the database are explicitly declared, it is not necessary for the compiler to check the typing. In this case, you can set the options so that the compiler only executes the translation phase of the method. This saves at least 50% in compilation time.
You can speed up your methods by using compiler directives. For more details on this subject, refer to the Optimization Hints section. To give a simple example, suppose you need to increment a counter using a local variable. If you do not declare the variable, the compiler assumes that is a Real. If you declare it as a Longint, the compiled database will perform more efficiently. On a PC, for instance, a Real takes 8 bytes, but if you type the counter as a Longint, it only uses 4 bytes. Incrementing an 8-byte counter obviously takes longer than incrementing a 4-byte one.
Compiler directives can be handled in two different ways, depending on whether or not you want the compiler to type your variables.
The compiler must respect the identification criteria of the variables.
There are two possibilities:
1) If the variables are not typed, the compiler can do it for you automatically. Whenever possible––as long as there is no ambiguity––the compiler determines a variable's type from the way it is used. For example, if you write:
V1:=True
the compiler determines that variable V1 is of data type Boolean.
By the same token, if you write:
V2:="This is a sample phrase"
the compiler determines that V2 is a Text type variable.
The compiler is also capable of establishing the data type of a variable in less straightforward situations:
V3:=V1 `V3 is of the same type as V1
V4:=2*V2 `V4 is of the same type as V2
The compiler also determines the data type of your variables according to calls to 4D commands and according to your methods. For example if you pass a Boolean type parameter and a Date type parameter to a method, the compiler assigns the Boolean type and the Date type to the local variables $1 and $2 in the called method.
When the compiler determines the data type by inference, unless indicated otherwise in the Preferences, it never assigns the limiting data types: Integer, Longint or String. The default type assigned by the compiler is always the widest possible. For example, if you write:
Number:=4
the compiler assigns the Real data type to Number, even though 4 happens to be an integer. In other words, the compiler does not rule out the possibility that, under other circumstances, the variable's value might be 4.5.
If it is appropriate to type a variable as Integer, Longint or String, you can do so using a compiler directive. It is to your advantage to do so, because these data types occupy less memory and performing operations on them is faster.
If you have already typed your variables and are sure that your typing is coherent and complete, you may explicitly ask the compiler not to redo this work, using the compilation Preferences. In case your typing was not complete and exhaustive, at the time of compilation, the compiler will return errors requesting you to make the necessary modifications.
2) The compiler directive commands enable you to explicitly declare the variables used in your databases.
They are used in the following manner:
C_BOOLEAN(Var)
Through such directives, you inform the compiler to create a variable Var that will be a Boolean.
Whenever an application includes compiler directives, the compiler detects them and thus avoids guesswork.
A compiler directive has priority over deductions made from assignments or use.
Variables declared with the compiler directive C_INTEGER are actually the same as those declared by the directive C_LONGINT. They are, in fact, long integers between –2147483648 and +2147483647.
If you do not want the compiler to check your typing, you must give it a code to identify the compiler directives.
The convention to follow is:
Compiler directives for the process and interprocess variables and the parameters should be placed in one or more methods, the names of which begin with the key word Compiler.
By default, the compiler lets you automatically generate five types of Compiler methods, which group together the directives for variables, arrays and method parameters (for more information about this point, refer to the Design Reference manual).
Note: The syntax for declaring these parameters is the following:
Directive (methodName;parameter). This syntax is not executable in interpreted mode.
Particular parameters
C_LONGINT($0)
If(Form event=On Drag Over)
$0:=0
...
If($DataType=Is picture)
$0:=-1
End if
...
End if
Compiler directives remove any ambiguity concerning data types. Although a certain rigor is necessary, this does not necessarily mean that the compiler is intolerant of any and every inconsistency.
For example, if you assign a real value to a variable declared as an Integer, the compiler does not regard either assignment as a type conflict and assigns the corresponding values according to your directives. So, if you write:
C_INTEGER(vInteger)
vInteger:=2.5
The compiler does not regard it as a data type conflict that will prevent compilation; instead, the compiler simply rounds off to the closest integer value (3 instead of 2.5).
Product: 4D
Theme: Compiler
Error messages
Optimization Hints
Syntax Details
Typing Guide
4D Language Reference ( 4D v14 R2)
4D Language Reference ( 4D v14 R3)
4D Language Reference ( 4D v14.3)
4D Language Reference ( 4D v14 R4)
Inherited from : Using Compiler Directives ( 4D v11 SQL Release 6)