Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite IPAddress without union #8829

Closed
wants to merge 1 commit into from

Conversation

safocl
Copy link
Contributor

@safocl safocl commented Nov 3, 2023

Rewrite IPAddress without union

Using a union allowed undefined behavior for array-like INPUT and OUTPUT arguments through a 32-bit integer (and vice versa).

C++ standard says (https://timsong-cpp.github.io/cppwp/n4659/class.union#1):
"At most one of the non-static data members of an object of union type
can be active at any time, that is, the value of at most one of the
non-static data members can be stored in a union at any time. [ Note:
One special guarantee is made in order to simplify the use of unions:
If a standard-layout union contains several standard-layout structs
that share a common initial sequence, and if a non-static data member
of an object of this standard-layout union type is active and is one
of the standard-layout structs, it is permitted to inspect the common
initial sequence of any of the standard-layout struct members; see
[class.mem].  — end note ]"

and (https://timsong-cpp.github.io/cppwp/n4659/class.mem#22):
"Two standard-layout unions are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible types."

you can't hope that compilers don't seem to do undefined behavior at the moment

note: this PR is recreated #8819 PR -- to fix #8819 (comment)

- Using a union allowed undefined behavior for array-like INPUT and OUTPUT arguments through a 32-bit integer (and vice versa).

C++ standard says (https://timsong-cpp.github.io/cppwp/n4659/class.union#1):
"At most one of the non-static data members of an object of union type
can be active at any time, that is, the value of at most one of the
non-static data members can be stored in a union at any time. [ Note:
One special guarantee is made in order to simplify the use of unions:
If a standard-layout union contains several standard-layout structs
that share a common initial sequence, and if a non-static data member
of an object of this standard-layout union type is active and is one
of the standard-layout structs, it is permitted to inspect the common
initial sequence of any of the standard-layout struct members; see
[class.mem].  — end note ]"

and (https://timsong-cpp.github.io/cppwp/n4659/class.mem#22):
"Two standard-layout unions are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible types."

you can't hope that compilers don't seem to do undefined behavior at the moment
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _address;
alignas(alignof(uint32_t)) std::array<uint8_t,4> _address{}; // IPv4 address
Copy link
Contributor

@TD-er TD-er Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does std::array initialize with a zero value?
You did remove the default constructor, so it must be set to zero here.

Edit:
Yep, the {} does indeed initialize all elements.
See: https://en.cppreference.com/w/cpp/container/array

I was a bit worried it might only initialize the array and not just its elements as that was indeed an issue with C++11 requiring double braces.

@me-no-dev
Copy link
Member

Before we can do anything here, you need to first propose this upstream: https://github.com/arduino/ArduinoCore-API/blob/master/api/IPAddress.cpp

safocl added a commit to safocl/ArduinoCore-API that referenced this pull request Nov 8, 2023
Using a union allowed undefined behavior for 8-bit integer INPUT and OUTPUT arguments through a 32-bit integer (and vice versa).
Write throught union::uint8_t[16] and read thoutght union::uint32_t[4]
is a undefined behavior.

C++ standard says (https://timsong-cpp.github.io/cppwp/n4659/class.union#1):
"At most one of the non-static data members of an object of union type
can be active at any time, that is, the value of at most one of the
non-static data members can be stored in a union at any time. [ Note:
One special guarantee is made in order to simplify the use of unions:
If a standard-layout union contains several standard-layout structs
that share a common initial sequence, and if a non-static data member
of an object of this standard-layout union type is active and is one
of the standard-layout structs, it is permitted to inspect the common
initial sequence of any of the standard-layout struct members; see
[class.mem].  — end note ]"

and (https://timsong-cpp.github.io/cppwp/n4659/class.mem#22):
"Two standard-layout unions are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible types."

you can't hope that compilers don't seem to do undefined behavior at the moment

Also created espressif/arduino-esp32#8829 PR dependent on changing the current API.
@safocl
Copy link
Contributor Author

safocl commented Nov 8, 2023

Before we can do anything here, you need to first propose this upstream: https://github.com/arduino/ArduinoCore-API/blob/master/api/IPAddress.cpp

I created PR

@me-no-dev
Copy link
Member

Thanks! Keep us posted :)

@VojtechBartoska VojtechBartoska added this to the 3.0.0-RC1 milestone Nov 28, 2023
@me-no-dev me-no-dev removed this from the 3.0.0-RC1 milestone Dec 13, 2023
@me-no-dev
Copy link
Member

@VojtechBartoska removed the milestone, because this is pending being merged upstream into the official Arduino API first. We will sync with what they currently have for 3.0.0 and later merge this, once updated upstream.

@safocl
Copy link
Contributor Author

safocl commented Dec 13, 2023

@VojtechBartoska removed the milestone, because this is pending being merged upstream into the official Arduino API first. We will sync with what they currently have for 3.0.0 and later merge this, once updated upstream.

They said that no std::* objects can be used to implement internal components.
I have rewritten it with a C-style array and am waiting for acceptance.

@me-no-dev
Copy link
Member

@safocl you will update this PR, once merged upstream, correct?

@safocl
Copy link
Contributor Author

safocl commented Dec 13, 2023

@safocl you will update this PR, once merged upstream, correct?

yes, i will...
All that remains is to find out which version they will accept the work on, then I will immediately update it to the same type.

@me-no-dev me-no-dev marked this pull request as draft January 23, 2024 14:44
@me-no-dev
Copy link
Member

because we are clearing PRs. I will close this one for now and @safocl can reopen it when main Arduino merges the proposal

@me-no-dev me-no-dev closed this Jan 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

4 participants