Why do I get "Constant expression violates subrange bounds" for HKEY_-constants in Delphi XE2 64bit?
64-bit, delphi, delphi-xe2, winapi
Solution
On the 64 bit compiler the actual value of `HKEY_CLASSES_ROOT` is:
FFFFFFFF80000000
That's because the cast to `Integer` makes `80000000` into a negative number. And then the conversion to unsigned leads to `FFFFFFFF80000000`. Note that this value is correct. The declaration in the windows header file is:
#define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) )
and when you include the header file and inspect the value of `HKEY_CLASSES_ROOT` in a C++ program, it is the exact same value as for the Delphi declaration.
And then we can solve the puzzle from the Delphi documentation which states that the selectors in a case statement can only be:
any expression of an ordinal type smaller than 32 bits
You have no choice but to replace your `case` statement with an `if` statement.
Problem
When I compile the following code in Delphi XE2 for the target platform 64-bit Windows ... ``` function HKeyToString(_HKey: HKey): string; begin case _HKey of HKEY_CLASSES_ROOT: result := 'HKEY_CLASSES_ROOT'; // do not translate HKEY_CURRENT_USER: result := 'HKEY_CURRENT_USER'; // do not translate HKEY_LOCAL_MACHINE: result := 'HKEY_LOCAL_MACHINE'; // do not translate HKEY_USERS: result := 'HKEY_USERS'; // do not translate HKEY_PERFORMANCE_DATA: result := 'HKEY_PERFORMANCE_DATA'; // do not translate HKEY_CURRENT_CONFIG: result := 'HKEY_CURRENT_CONFIG'; // do not translate HKEY_DYN_DATA: result := 'HKEY_DYN_DATA'; // do not translate else Result := Format(_('unknown Registry Root Key %x'), [_HKey]); end; end; ``` ... I get warnings for each of the HKEY_-Constants: "W1012 Constant expression violates subrange bounds" I checked the declarations in Winapi.Windows (with Ctrl+Leftclick on the identifiers): ``` type HKEY = type UINT_PTR; {...} const HKEY_CLASSES_ROOT = HKEY(Integer($80000000)); ``` These look fine to me. Why does the compiler still think there is a problem?