Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Language question: accessing union members

Language question: accessing union members

Scheduled Pinned Locked Moved C / C++ / MFC
questionperformance
5 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Phil Hamer
    wrote on last edited by
    #1

    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?

    V D M 3 Replies Last reply
    0
    • P Phil Hamer

      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?

      V Offline
      V Offline
      vcplusplus
      wrote on last edited by
      #2

      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++.

      P 1 Reply Last reply
      0
      • V vcplusplus

        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++.

        P Offline
        P Offline
        Phil Hamer
        wrote on last edited by
        #3

        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....

        1 Reply Last reply
        0
        • P Phil Hamer

          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?

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          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 two WORDs by accessing s.wValue1 and s.wValue2. It looks odd but it definitely has its uses.

          1 Reply Last reply
          0
          • P Phil Hamer

            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?

            M Offline
            M Offline
            Marissa182
            wrote on last edited by
            #5

            just use an overloded operatoer FILETIME operator-(FILETIME &ft, FILETIME &ft1);

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups