13.01.2018, 17:20
(
Последний раз редактировалось Yashas; 15.01.2018 в 12:20.
)
Destructors in PAWN
This is not documented in the PAWN Language Guide which is why this feature was unknown for quite a long time (11 years?). The implementer guide hints about destructors at few places though.
Declaration of destructors:
At the first glance, it feels like the destructor works only with arrays. However, this is not true. The above function signature is applicable to both arrays and variables.
The first parameter is essentially behaves as a reference variable in case of variables being destroyed and as a reference array in case of arrays. This means that you can know where the object was stored in memory. The tag of this parameter participates in overload resolution.
The second parameter provides the size of the first parameter. The tag of this parameter is ignored during overload resolution. By that, I mean to say that: if you have `new arr[tag1:10], arr2[tag2:20];", the same destructor will be called for both. In fact, you cannot create two destructors that differ only in the tag of the this parameter.
The destructor cannot have a return type. The compilation will fail if all the dimensions of an array (which has a destructor) is not explicitly given during declaration (even if all the sizes can be determined at compile-time).
Examples:
will result in:
will give:
Multi-dimensional arrays
The destructor is not called for multi-dimensional arrays in the default PAWN compiler.
The Zeex compiler calls the destructor for the data of the array. The first parameter of the destructor will point to the start of the data of the array and the second parameter will provide the total number of elements in the array. The entire multi-dimensional array has to be accessed as if it were a single dimensional array.
[FIXES PENDING]
Order of destruction:
The destructors are called in the reverse order of declaration (most recently declared will be destroyed first).
"c" will be destroyed first, "b" will be destroyed next and "a" finally.
Notes:
This is not documented in the PAWN Language Guide which is why this feature was unknown for quite a long time (11 years?). The implementer guide hints about destructors at few places though.
Declaration of destructors:
Код:
operator~(MyTag:arr[], size) { }
The first parameter is essentially behaves as a reference variable in case of variables being destroyed and as a reference array in case of arrays. This means that you can know where the object was stored in memory. The tag of this parameter participates in overload resolution.
The second parameter provides the size of the first parameter. The tag of this parameter is ignored during overload resolution. By that, I mean to say that: if you have `new arr[tag1:10], arr2[tag2:20];", the same destructor will be called for both. In fact, you cannot create two destructors that differ only in the tag of the this parameter.
The destructor cannot have a return type. The compilation will fail if all the dimensions of an array (which has a destructor) is not explicitly given during declaration (even if all the sizes can be determined at compile-time).
Examples:
Код:
#include <a_samp> operator~(Tag:arr[], size) { new address; #emit LOAD.S.pri arr #emit STOR.S.pri address printf("Destructor Called: address:%d, first-value:%d, size:%d", address, _:arr[0], size); } main () { new Tag:arr[] = {Tag:1, Tag:2, Tag:3}; { new Tag:var; } }
Код:
Destructor Called: address:16584, first-value:0, size:1 Destructor Called: address:16588, first-value:1, size:3
Код:
#include <a_samp> operator~(Tag:arr[], size) { new address; #emit LOAD.S.pri arr #emit STOR.S.pri address printf("Destructor Called: address:%d, first-value:%d, size:%d", address, _:arr[0], size); } func(&Tag:a, Tag:b = Tag:5) { return; } main () { new Tag:x = Tag:10; func(x); printf("end of main"); }
Код:
Destructor Called: address:16628, first-value:5, size:1 end of main Destructor Called: address:16632, first-value:10, size:1
The destructor is not called for multi-dimensional arrays in the default PAWN compiler.
The Zeex compiler calls the destructor for the data of the array. The first parameter of the destructor will point to the start of the data of the array and the second parameter will provide the total number of elements in the array. The entire multi-dimensional array has to be accessed as if it were a single dimensional array.
[FIXES PENDING]
Order of destruction:
The destructors are called in the reverse order of declaration (most recently declared will be destroyed first).
Код:
new Tag:a = 2, Tag2:b = 5; { new Tag3:c; }
Notes:
- destructors are not called for global variables
- destructors are called for variables and arrays only (they are not called for references or array references)
- destructors are called for local static variables every time the function is called (it shouldn't be called at all given that destructors are not called for globals) Issue at Zeex's compiler Repo
- destructors are called for arguments only at explicit returns, i.e: destructors for arguments are not called unless you add a return statement at the end of the function
Issue at Zeex's compiler Repo - destructors are not called for multi-dimensional arrays in the default compiler and are called wrongly in the Zeex compiler