6.2.1 Valid - JulTob/Ada GitHub Wiki
The Valid
attribute returns a Boolean value. For access types, it checks if the access value is null or not. For scalar types like integers or enumerations, it checks if the value falls within the defined range or is otherwise valid according to Ada’s strong typing rules.
The 'Valid
attribute is most commonly useful with unchecked or low-level operations where Ada’s strong typing system isn’t fully enforced, such as in cases involving unchecked conversions or access types.
In typical scenarios with properly declared variables and regular operations, Ada’s strong typing and range checks will prevent invalid assignments, raising exceptions like Constraint_Error before the 'Valid attribute is even evaluated. However, there are specific situations where 'Valid can return False without raising an exception:
Access Types (Pointers)
When dealing with access types (pointers), the 'Valid attribute is used to check if the access value is pointing to a valid memory location or if it is null. If an access variable holds an invalid address, Ada won’t immediately raise an exception, but you can check its validity with 'Valid.
with Ada.Text_IO; use Ada.Text_IO;
procedure Access_Valid_Example is
type Int_Ptr is access Integer;
Ptr : Int_Ptr := null; -- Pointer initially null
begin
Put_Line("Is Ptr valid? " & Boolean'Image(Ptr'Valid));
-- Will print 'FALSE'
-- Dynamically allocate memory and point Ptr to it
Ptr := new Integer'(10);
Put_Line("Is Ptr valid after allocation? " & Boolean'Image(Ptr'Valid));
-- Will print 'TRUE'
-- Deallocate memory (make the pointer invalid)
Ptr := null;
Put_Line("Is Ptr valid after null assignment? " & Boolean'Image(Ptr'Valid));
-- Will print 'FALSE'
end Access_Valid_Example;
Unchecked Conversion
When you use Unchecked_Conversion in Ada, you are essentially bypassing the strict type-checking system, allowing conversions that the compiler would normally disallow. The 'Valid attribute becomes useful in this case because a result of unchecked conversion might produce an invalid value that Ada’s type-checking system cannot catch automatically.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;
procedure Unchecked_Conversion_Valid is
type My_Integer is new Integer range 1 .. 100;
type Raw_Bits is mod 2**32;
-- Declare an unchecked conversion from Raw_Bits to My_Integer
function To_My_Integer is new Ada.Unchecked_Conversion(Raw_Bits, My_Integer);
X : My_Integer;
Bits : Raw_Bits := 500; -- Value outside My_Integer's range
begin
X := To_My_Integer(Bits); -- This bypasses Ada's range checks
Put_Line("Is X valid after unchecked conversion? " & Boolean'Image(X'Valid)); -- Could print 'FALSE'
end Unchecked_Conversion_Valid;
In this example, the Unchecked_Conversion may result in an invalid value for X, and Ada will not raise a Constraint_Error. However, 'Valid can be used to check if the resulting value is valid for the type My_Integer. If the conversion produces a value outside the range of My_Integer, 'Valid will return False.
But if you are doing this much work, maybe you should just use error handling, mate.
Unchecked_Deallocation
When memory is manually deallocated using Unchecked_Deallocation, access types can become invalid without automatically raising an exception. Using 'Valid helps in checking whether an access value is still valid after deallocation.
Key Situations where 'Valid might return False without an immediate error:
- Access types that are null or have been deallocated.
- Unchecked conversions where the type constraints are bypassed.
- Manual memory management with Unchecked_Deallocation or invalid pointer operations.
- Low-level hardware interfacing or system-level programming, where hardware values might change unexpectedly or unchecked regions of memory are accessed.
In all these cases, 'Valid gives you a way to check the validity of a variable’s value without triggering a runtime exception, making it especially useful when working with low-level or unsafe operations where invalid values can sneak in without the usual safeguards of Ada’s strong typing.