Language question: accessing union members
-
I have a FILETIME struct that I want to perform arithmetic on (subtract a week from it). To do this, I need to convert it to a 64-bit integer, do the arithmetic, then convert back to a FILETIME. I've seen examples that do this with the ULARGE_INTEGER union. Something like this:
FILETIME ft; // ...set ft... ULARGE_INTEGER uli; // Copy ft to uli using uli's 2-DWORD struct uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // Do arithmetic with uli's __int64 uli.QuadPart -= ... // Convert back to FILETIME ft.dwLowDateTime = uli.LowPart; ft.dwHighDateTime = uli.HighPart;
where the QuadPart is overlayed in memory with the LowPart/HighPart (since it's a union). But is this legal... to set one union member and then read a different union member? Yes, I've tried it and it does work, but is it truly correct according to the language? -
I have a FILETIME struct that I want to perform arithmetic on (subtract a week from it). To do this, I need to convert it to a 64-bit integer, do the arithmetic, then convert back to a FILETIME. I've seen examples that do this with the ULARGE_INTEGER union. Something like this:
FILETIME ft; // ...set ft... ULARGE_INTEGER uli; // Copy ft to uli using uli's 2-DWORD struct uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // Do arithmetic with uli's __int64 uli.QuadPart -= ... // Convert back to FILETIME ft.dwLowDateTime = uli.LowPart; ft.dwHighDateTime = uli.HighPart;
where the QuadPart is overlayed in memory with the LowPart/HighPart (since it's a union). But is this legal... to set one union member and then read a different union member? Yes, I've tried it and it does work, but is it truly correct according to the language?typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; }; ULONGLONG QuadPart; } ULARGE_INTEGER;
You should not have any problems since QuadPart is 64 bits, whereas LowPart and HighPart are 32 bits. LowPart holds the first 32 bits and HighPart represents the other 32 bits. I hope this is correct since I never use unions and it has been 10 years since I have studied c++. -
typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; }; ULONGLONG QuadPart; } ULARGE_INTEGER;
You should not have any problems since QuadPart is 64 bits, whereas LowPart and HighPart are 32 bits. LowPart holds the first 32 bits and HighPart represents the other 32 bits. I hope this is correct since I never use unions and it has been 10 years since I have studied c++.Yes, I realize the layout of the union. My question is sort of a tricky one that someone who is very familiar with the C or C++ language may know. Each language has specifications for what is and is not defined behavior. If something is not defined behavior, that means it may actually work sometimes or all the time, but it is still incorrectly coded. I seem to remember that it is illegal to assign to one union member and then read from a different union member. But I'm not sure, hence the question....
-
I have a FILETIME struct that I want to perform arithmetic on (subtract a week from it). To do this, I need to convert it to a 64-bit integer, do the arithmetic, then convert back to a FILETIME. I've seen examples that do this with the ULARGE_INTEGER union. Something like this:
FILETIME ft; // ...set ft... ULARGE_INTEGER uli; // Copy ft to uli using uli's 2-DWORD struct uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // Do arithmetic with uli's __int64 uli.QuadPart -= ... // Convert back to FILETIME ft.dwLowDateTime = uli.LowPart; ft.dwHighDateTime = uli.HighPart;
where the QuadPart is overlayed in memory with the LowPart/HighPart (since it's a union). But is this legal... to set one union member and then read a different union member? Yes, I've tried it and it does work, but is it truly correct according to the language?That's the whole purpose of a
union
- to be able to access a member by more than one name.union u
{
DWORD dwValue;
struct s
{
WORD wValue1;
WORD wValue2;
};
};Now I can assign a value to
u.dwValue
and read it as twoWORD
s by accessings.wValue1
ands.wValue2
. It looks odd but it definitely has its uses. -
I have a FILETIME struct that I want to perform arithmetic on (subtract a week from it). To do this, I need to convert it to a 64-bit integer, do the arithmetic, then convert back to a FILETIME. I've seen examples that do this with the ULARGE_INTEGER union. Something like this:
FILETIME ft; // ...set ft... ULARGE_INTEGER uli; // Copy ft to uli using uli's 2-DWORD struct uli.LowPart = ft.dwLowDateTime; uli.HighPart = ft.dwHighDateTime; // Do arithmetic with uli's __int64 uli.QuadPart -= ... // Convert back to FILETIME ft.dwLowDateTime = uli.LowPart; ft.dwHighDateTime = uli.HighPart;
where the QuadPart is overlayed in memory with the LowPart/HighPart (since it's a union). But is this legal... to set one union member and then read a different union member? Yes, I've tried it and it does work, but is it truly correct according to the language?just use an overloded operatoer FILETIME operator-(FILETIME &ft, FILETIME &ft1);