I've never been very satisfied with these approaches for C where you hope the compiler does the right thing. It makes sense to provide some C implementation for portability's sake but any sizeable reordering cries out for a handtuned, processor specific, approach (and the non-sizeable probably doesn't require high speed). I would expect any SIMD instruction set to include a shuffle.
The Byte Order Fiasco
151–160 of 378 posts
Re: The Byte Order Fiasco
#152 (uint32_t)x[0]
Of course, this requires that x[0] be unsigned.Re: The Byte Order Fiasco
#153In an ideal world which endian format would one go for?
https://fgiesen.wordpress.com/2014/10/25/little-endian-vs-bi...
Of all those reasons, the only one I can make sense of is the "I can’t transparently widen fields after the fact!", and that one is way too niche to explain anything.
Re: The Byte Order Fiasco
#154Earlier quoted context omitted.
Not really. Unicode is a variable width abstract encoding; a single character can be made up of multiple code points. For Unicode, 32-bit bytes would be an incredibly wasteful in memory encoding.
One byte = one "character" makes for much easier programming. Text generally uses a small fraction of memory and storage these days.
Only if you are naively operating in the Anglosphere / world where the most complex thing you have to handle is larger character sets. In reality, there's ligatures, diacritics, combining characters, RTL, nbsp, locales, and emoji (with skin tones!). Not to mention legacy encoding.
And no, it does not use a "small fraction of memory and storage" in a huge range of applications, to the point where some regions have transcoding proxies still.
Re: The Byte Order Fiasco
#155Earlier quoted context omitted.
We really should have moved to 32 bit bytes when moving to 64 bit words. Would have simplified Unicode considerably.
Use Erlang. It has 32-bit char.
However, since Unicode is limited to 21-bits by utf-16 encoding, a unicode code point will fit in a small integer.
[1] unless you use binaries, which is often a better choice.
Re: The Byte Order Fiasco
#156Earlier quoted context omitted.
Who decides what methods to add to the bytes type/abstraction? If I have a 3 byte big endian integer can I access it easily in rust without resorting to shifts? In C++ I could probably create a fairly convincing big_uint24_t type and use it in a packed struct and there would be no inconsistencies with how it's used with respect to the more common varieties
In Rust, [u8; N] and &[u8] are both primitive types, and not abstractions. It's possible to create an abstraction around either (the former even more so now with const generics), but that's not necessary. It's also possible to use "extension traits" to add methods, even to existing and built-in types[1]. I'm not sure about a 3 byte big endian integer. I mean, that's going to compile down to some combination of shifti…
I think there's no need for explicit shifts. You need to memcpy anyway to deal with alignment issues, so you may as well just copy in to the last 3 bytes of a zero-initialized, big endian, 32bit uint.
Re: The Byte Order Fiasco
#157Earlier quoted context omitted.
Correct me if I'm wrong, but your example is just using a library to do the same task, rather than illustrating any difference between C and C++. If you want to pull boost in to do this, that's great, but that hardly seems like a fair comparison to the OP, since instead of implementing code to solve this problem yourself you're just importing someone else's code.
No, the fact that this can be done in a library and looks like a native language feature demonstrates the power of C++ as a language. This example is demonstrating: - First class treatment of user (or library) defined types - Operator overloading - The fact that it produces fast machine code. Try changing big_uint32_t to regular uint32_t to see how this changes. When you use the later ubsan will introduce a trap for…
Re: The Byte Order Fiasco
#158Earlier quoted context omitted.
Big-endian is natural when you're comparing numbers, which is probably why people represent numbers in a big-endian fashion. Little-endian is natural with casts because the address doesn't change, and it's the order in which addition takes place.
I feel like big endian is more _intuitive_ because that's what our number notation has evolved to be. But more _natural_ is little endian because, well, it's just more straightforward to have the digits' magnitude be in ascending order (2^0, 2^1, 2^2, 2^3...) instead of putting it in reverse. Plus you encounter less roadblocks in practice with little endian (e.g. address changes with casts) which is often a sign of g…
All human number systems I've ever seen write numbers out as big Endian (yes, even Roman numerals), so I'm really struggling to see how that wouldn't be considered natural.
Re: The Byte Order Fiasco
#159Byte order is one of the great unnecessary historical fuck ups in computing. A similar one is that signedness of char is machine dependent. It's typically signed on Intel and unsigned on ARM. Sigh!
the greatest of all is lisp not being the most mainstream language, and we can only blame the lisp companies for this fiasco. in an ideal world we all would be using a lisp with parametric polymorphism. from highest level abstractions to machine level, all in one language.
Re: The Byte Order Fiasco
#160This is why, in 2021, the mantra that C is a good language for these low level byte twiddling tasks needs to die. Dealing with alignment and endianness properly requires a language that allows you to build abstractions. The following is perfectly well defined in C++, despite looking like almost the same as the original unsafe C: #include #include using namespace boost::endian; unsigned char b[5] = {0x80,0x01,0x02,0x0…
C is perfect for these problems. I like teaching the endian serialization problem because it broaches so many of the topics that are key to understanding C/C++ in general. Even if we choose to spend the majority of our time plumbing together functions written by better men, it's nice to understand how the language is defined so we could write those functions, even if we don't need to.