Treating structs like FILETIME as UInt64/Int64

delphi

Solution

It's a largely non-issue on the architectures that Delphi supports. The x86 and x64 architectures forgive you if you access mis-aligned data. On the other hand, accessing mis-aligned data on Itanium will result in runtime errors. But Delphi never targeted Itanium.

The issue that is significant is record layout. An Int64 has alignment of 8. But FILETIME and LUID have alignment of 4. Which is why LUID_AND_ATTRIBUTES is marked with an explicit $ALIGN 4.

If you are going to declare FILETIME and LUID to be Int64 then you need to take special care with record layout every time you include one in a record.

Problem

The question arise after I read a MSDN Blog article, Why can't you treat a FILETIME as an __int64?. The article said that casting a `FILETIME` to an `__int64` can create a misaligned pointer. `FILETIME`, `LUID`, and `LUID_AND_ATTRIBUTES` structs declared in Windows header as follows: ``` typedef struct FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } typedef struct LUID { ULONG LowPart; LONG HighPart; } typedef struct LUID_AND_ATTRIBUTES { LUID Luid; DWORD Attributes; } ``` Since `FILETIME` and `LUID` structs has a similar layout, therefore treating a `LUID` as an `__int64` also can create a misaligned pointer. However, `Windows.pas` (Delphi XE3 here) practises this--, for example: ``` {$ALIGN 4} LUID_AND_ATTRIBUTES = record Luid : Int64; // Here, LUID is treated as Int64 Attributes: DWORD; end; {$ALIGN ON} ``` another example is ``` function LookupPrivilegeValue(lpSystemName, lpName: LPCWSTR; var lpLuid: Int64): BOOL; stdcall; // LUID is treated as Int64 ``` How to safely treat structs like `FILETIME` or `LUID` directly as `UInt64`/`Int64`? What is the key?

Original source