Skip to content

Undefined behavior when using union #42843

@safocl

Description

@safocl

Microsoft PowerToys version

main branch

Installation method

GitHub

Area(s) with issue?

General

Steps to reproduce

compile and run

✔️ Expected Behavior

not undefined behavior
https://eel.is/c++draft/defns.undefined

❌ Actual Behavior

undefined behavior
https://eel.is/c++draft/defns.undefined

Additional Information

In a standard-layout union with an active member of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated.

If a program attempts to access ([defns.access]) the stored value of an object through a glvalue through which it is not type-accessible, the behavior is undefined.

https://eel.is/c++draft/class.mem#general-30
https://eel.is/c++draft/class.prop#10
https://eel.is/c++draft/class.union#general-2
https://eel.is/c++draft/basic.lval#11.sentence-2

https://eel.is/c++draft/dcl.init.aggr#5.4
https://eel.is/c++draft/dcl.init.aggr#5.5

except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union], [class.copy.ctor], and [class.copy.assign], and except as described in [allocator.members]

https://eel.is/c++draft/basic.life#2.sentence-3
https://eel.is/c++draft/class.union#general-example-2

https://learn.microsoft.com/en-us/cpp/cpp/unions?view=msvc-170

but

SystemTimeToFileTime(&m_fileTime, &ft1.fileTime);

uses an inactive union member when do assignment

if (ft2.ul.QuadPart != ft1.ul.QuadPart)

access to inactive union member.

even using it when initializing the first member and using the second member will be undefined behavior

union timeunion
{
    FILETIME fileTime;
    ULARGE_INTEGER ul;
};

https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
and
https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ularge_integer-r1
are incompatible in layout and do not have a common initial sequence.
https://godbolt.org/z/3vshTa1x7

example:
https://godbolt.org/z/n98vP6ae4

p.s.
https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime#remarks describes

It is not recommended that you add and subtract values from the FILETIME structure to obtain relative times. Instead, you should copy the low- and high-order parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic on the QuadPart member, and copy the LowPart and HighPart members into the FILETIME structure.

Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.

Other Software

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugSomething isn't workingNeeds-TriageFor issues raised to be triaged and prioritized by internal Microsoft teamsProduct-PowerRenameRefers to the PowerRename PowerToyStatus-In progressThis issue or work-item is under development

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions