-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Use u32::from_ne_bytes to fix a FIXME and add comment about that #75086
Conversation
@bors r+ rollup awesome! |
📌 Commit edcb4058be815b5ab061f8efb1d235099de633fd has been approved by |
Eh CI is falling. I don't know if it is spurious or not. |
Sounds related at least, did these pass for you locally? @bors r- |
library/std/src/net/ip.rs
Outdated
), | ||
}, | ||
} | ||
Ipv4Addr { inner: c::in_addr { s_addr: u32::from_be_bytes([a, b, c, d]) } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe the fixme was wrong? I can never get be/le order right...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jup, it's wrong: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2920668bc321a75501f2bc033ed9f893
I guess we need from_le_bytes
here. Makes sense since the function says the bytes already have to be in the right order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Will run the test locally first and update the PR later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think about it again. Do we guarantee that c::in_addr
in big endian?
I get the feelings that we are missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect u32::from_ne_bytes([a, b, c, d])
, since we want to store those as abcd
(an internet address is stored in big-endian byte ordering). This would be equivalent to the old implementation. The u32::from_le_bytes([a, b, c, d])
swaps the order on big-endian targets to dcba
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those endiannesses are confusing in practice. Hope we have an way to enforce this in type system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, judge by assembly, I think ne is the correct answer: https://rust.godbolt.org/z/e5ahnK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very likely that I was wrong in the TODO -- I think I was wrong in #57740 (comment) too
Done. |
@bors r+ |
📌 Commit aca0258 has been approved by |
rust/library/std/src/net/ip.rs Lines 383 to 386 in 7637cbb
But we are taking Little Endian in this PR. |
isn't |
(should probably use |
ne is native byte order, could be le and be. |
oh, I thought it was In that case the current use of |
I mean, the tests pass so the current conversion is right. This PR could be merged but I think we need a issue to validate all assignments |
Use u32::from_le_bytes to fix a FIXME `u32::from_be_bytes` has been const stable since 1.44.
library/std/src/net/ip.rs
Outdated
), | ||
}, | ||
} | ||
Ipv4Addr { inner: c::in_addr { s_addr: u32::from_le_bytes([a, b, c, d]) } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these from_*_bytes
return a native-endian u32
. Right now you're presenting the bytes in BE order but calling it LE -- that will sort of work on LE targets, but will get swapped on BE targets to the wrong order.
I think it should really use from_be_bytes
, and then you still need u32::to_be
around it.
@bors r- |
Actually yes, |
Yes, you are right. The original code always ends with
That sounds correct to me as well as it is the result of |
I said "On a big-endian machine:", then |
Yeah, it ultimately looks identical either way here: https://rust.godbolt.org/z/o4M1zz |
Hmm, this is basically the inverse of pub fn octets(&self) -> [u8; 4] {
// This returns the order we want because s_addr is stored in big-endian.
self.inner.s_addr.to_ne_bytes()
} So it seem like the right implementation here might just be pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
// s_addr is stored in big-endian on all machines, so the array is provided in big-endian and
// the native endian conversion method is used so that it's never swapped.
Ipv4Addr { inner: c::in_addr { s_addr: u32::from_ne_bytes([a, b, c, d]) } }
} |
@scottmcm Yes -- and I think your comment would nicely explain what's going on there. |
Co-authored-by: Weiyi Wang <wwylele@gmail.com> Co-authored-by: Adam Reichold <adam.reichold@t-online.de> Co-authored-by: Josh Stone <cuviper@gmail.com> Co-authored-by: Scott McMurray <scottmcm@users.noreply.github.com> Co-authored-by: tmiasko <tomasz.miasko@gmail.com>
Thanks all. I recommitted and listed all of you as the commit author. |
Note about endianness of returned value of {integer}::from_be_bytes and friends [`u32::from_be`](https://doc.rust-lang.org/nightly/src/core/num/mod.rs.html#2883-2892) documents about endianness of returned value. I was confused by endianness of `from_be_bytes` in rust-lang#75086 .
There is another interfere PR #75110 but I want this PR to land first because |
@bors r+ |
📌 Commit 30a1455 has been approved by |
☀️ Test successful - checks-actions, checks-azure |
Note about endianness of returned value of {integer}::from_be_bytes and friends [`u32::from_be`](https://doc.rust-lang.org/nightly/src/core/num/mod.rs.html#2883-2892) documents about endianness of returned value. I was confused by endianness of `from_be_bytes` in rust-lang#75086 .
u32::from_ne_bytes
has been const stable since 1.44.