Modos interpretado e compilado
4D applications can work in interpreted or compiled mode:
- in interpreted mode, statements are read and translated in machine language at the moment of their execution. You can add or modify the code whenever you need to, the application is automatically updated.
- in compiled mode, all methods are read and translated once, at the compilation step. Posteriormente, a aplicação contém apenas instruções de nível de montagem, já não é possível editar o código.
As vantagens da compilação são:
- Speed: Your database can run from 3 to 1,000 times faster.
- Code checking: Your database application is scanned for the consistency of code. São detectados conflitos tanto lógicos como sintácticos.
- Protection: Once your database is compiled, you can delete the interpreted code. Then, the compiled database is functionally identical to the original, except that the structure and methods cannot be viewed or modified, deliberately or inadvertently.
- Stand-alone double-clickable applications: compiled databases can also be transformed into stand-alone applications (.EXE files) with their own icon.
- Preemptive mode: only compiled code can be executed in preemptive processes.
Differences between interpreted and compiled code
Although application will work the same way in interpreted and compiled modes, there are some differences to know when you write code that will be compiled. The 4D interpreter is usually more flexible than the compiler.
|You cannot have a method with the same name as a variable.||No error is generated, but priority is given to the method|
|All variables must by typed, either through a compiler directive (ex: ||Variables can be typed on-the-fly (not recommended)|
|You cannot change the data type of any variable or array.||Changing the data type of a variable or an array is possible (not recommended)|
|You cannot change a one-dimensional array to a two-dimensional array, or change a two-dimensional array to a one-dimensional array.||Possível|
|Although the compiler will type the variable for you, you should specify the data type of a variable by using compiler directives where the data type is ambiguous, such as in a form.|
|A função |
|If you have checked the "Can be run in preemptive processes" property for the method, the code must not call any thread-unsafe commands or other thread-unsafe methods.||Preemptive process properties are ignored|
|The ||É sempre possível interromper 4D|
Utilização de directivas de compilação com o Intérprete
Compiler directives are not required for uncompiled databases. The interpreter automatically types each variable according to how it is used in each statement, and a variable can be freely retyped throughout the database.
Because of this flexibility, it is possible that a database can perform differently in interpreted and compiled modes.
Por exemplo, se escrever:
and elsewhere in the database, you write:
In this example,
MyInt is assigned the same value (3) in both the interpreted and compiled modes, provided the compiler directive is interpreted prior to the assignment statement.
The 4D interpreter uses compiler directives to type variables. When the interpreter encounters a compiler directive, it types the variable according to the directive. If a subsequent statement tries to assign an incorrect value (e.g., assigning an alphanumeric value to a numeric variable) the assignment will not take place and will generate an error.
The order in which the two statements appear is irrelevant to the compiler, because it first scans the entire database for compiler directives. The interpreter, however, is not systematic. It interprets statements in the order in which they are executed. That order, of course, can change from session to session, depending on what the user does. For this reason, it is important to design your database so that your compiler directives are executed prior to any statements containing declared variables.
Using pointers to avoid retyping
Uma variável não pode ser redigida de novo. However, it is possible to use a pointer to refer to variables of different data types. For example, the following code is allowed in both interpreted and compiled modes:
$p:=->$name //alvo de texto para o ponteiro
$p->:="Wesson" //atribui um valor de texto
//novo alvo de tipo diferente para o ponteiro
$p->:=55 //atribui um valor numérico
Imagine a function that returns the length (number of charaters) of values that can be of any type.
// Calc_Length (how many characters)
// $1 = pointer to flexible variable type, numeric, text, time, boolean C_POINTER($1)
Then this method can be called:
$vLength:=Calc_Length(->$var1)+Calc_Length(->$var2)+Calc_Length (->$var3)+Calc_Length(->$var4) ALERT("Total length: "+String($vLength))