Compiler Attributes
Go Up to Attributes (RTTI)
Some special attributes trigger certain features of Delphi compilers.
Ref
The Ref
attribute is used to qualify constant function parameters so that they are passed by reference (not by value) to the function. For more information, see Constant Parameters.
Volatile
The volatile
attribute is used to mark fields that are subject to change by different threads, so that code generation does not optimize copying the value in a register or another temporary memory location.
You can use the volatile
attribute to mark the following declarations:
- Variables (global and local)
- Parameters
- Fields of a record or a class.
You cannot use the volatile
attribute to mark the following declarations:
type
TMyClass = class
private
[volatile] FMyVariable: TMyType;
end;
Weak and Unsafe Attributes
weak
and unsafe
references was originally introduced as part of the ARC memory management support for mobile platforms. As ARC is now phased out, this feature remains available only for interface references. Weak
Weak is an interface reference that does not increase the reference count of the object they refer to. It is marked with the [weak]
modifier. This feature is only supported by Delphi.
You can use weak references in the following cases:
- To avoid increasing count references.
- To manage interface references. This means that the system keeps track of them when the actual object is deleted.
- To break the circular references between two objects with cross-references. When this happens, you end up with a memory leak.
As an example, consider the following interface accepting a reference to another interface of the same type, and a class implementing it with an internal reference:
type
ISimpleInterface = interface
procedure DoSomething;
procedure AddObjectRef(Simple: ISimpleInterface);
end;
TObjectOne = class(TInterfacedObject, ISimpleInterface)
private
AnotherObj: ISimpleInterface;
public
procedure DoSomething;
procedure AddObjectRef(Simple: ISimpleInterface);
end;
If you create two objects and cross-reference them, you end up with a memory leak:
var
One, Two: ISimpleInterface;
begin
One := TObjectOne.Create;
Two := TObjectOne.Create;
One.AddObjectRef(Two);
Two.AddObjectRef(One);
Now the solution available in Delphi is to mark the private field AnotherObj as a weak interface reference:
private
[weak] AnotherObj: ISimpleInterface;
With this change, the reference count is not modified when you pass the object as a parameter to the AddObjectRef call, it stays at 1, and it goes back to zero when the variables go out of scope, freeing the objects from memory.
Unsafe
An Unsafe reference is an interface reference that does not increase the reference count of the object they refer to. It is marked with the [unsafe]
modifier.
You can use unsafe when you want to create an interface reference that is kept out of the total count of references. For example:
procedure TForm3.Button2Click(Sender: TObject);
var
[unsafe] OneIntf: ISimpleInterface;
begin
OneIntf := TObjectOne.Create;
OneIntf.DoSomething;
end;
See Also
- Volatile (C++)