I've had plenty of opensource contributions over the years for some feature or other I don't care about. I used to accept these pull requests. But all too often, the person who wrote the patch disappears. Then for years I receive bug reports about a feature I didn't write and I don't care about. What do I do with those reports? Ignore them? Fix the bugs myself? Bleh.
I don't publish opensource projects so I can be a volunteer maintainer, in perpetuity, for someone else's feature ideas.
If its a small change, or something I would have done myself eventually, then fine. But there is a very real maintenance burden that comes from maintaining support for weird features and rare computer architectures. As this article points out, you need to actively test on real hardware to make sure code doesn't rust. Unfortunately I don't have a pile of exotic computers around that I can use to test my software. And you need to test software constantly or there's a good chance you'll break something and not notice.
That said, is there an easy way to run software in "big endian" mode on any modern computer? I'd happily run my test suite in big endian mode if I could do so easily.
"I don't have access to a test environment, but if you want to write a fix, let me know and I may be able to point you in the right direction" is a perfectly reasonable response.
It's also reasonable to say I simply do not use this software the same way you do. The individual is empowered to fork, contribute and/or collaborate.
QEMU userspace emulation is usually the easiest for most "normal" programs IMO. Once you set it up you just run the other architecture binaries like normal binaries on your test system (with no need to emulate a full system). Very much the same concept as Prism/Rosetta on Windows/macOS for running x86 apps on ARM systems except it can be any target QEMU supports.
Ensuring a code base indefinitely supports arbitrary architectures carries a substantial code architecture cost. Furthermore, it is difficult to guarantee testing going forward or that the toolchains available for those architectures will continue to evolve with your code base. I'm old enough to have lived this reality back when it was common. It sucked hard. I've also written a lot of code that was portable to some very weird silicon so I know what that entails. It goes far beyond endian-ness, that is just one aspect of silicon portability.
The expectation that people should volunteer their time for low ROI unpleasantness that has a high risk of being unmaintainable in the near future is unreasonable. There are many other facets of the code base where that time may be better invested. That's not "anti-portable", it is recognition of the potential cost to a large base of existing users when you take it on. The Pareto Principle applies here.
Today, I explicitly only support two architectures: 64-bit x86 and ARM (little-endian). It is wonderful that we have arrived at the point where this is a completely viable proposition. In most cases the cost of supporting marginal users on rare architectures in the year 2026 is not worth it. The computing world is far, far less fragmented than it used to be.
I'd say just the opposite; it nudges you towards well-factored approaches and ultimately carries a code architecture benefit, just like having automated tests or using structured programming.
This - and efforts to reintroduce BE should be resisted in the same way as people who want to drive on the other side of the road for pure whimsy.
I note that we've mostly converged on one set of floating point semantics as well, although across a range of bit widths.
Also: why not riscv?
Anyway, I think that most pain for being low level and portable is due to C and C++, and it's not as painful in Rust. In Rust it's not as common to use non-portable integers like C's int (there is isize/usize but they are used for indexing; logic is supposed to be done in i32/u32/i64/u64), and the Rust stdlib comes with excellent support for dealing with byte orders like https://doc.rust-lang.org/std/primitive.i32.html#method.to_b... (and for more support, usage of https://docs.rs/byteorder/latest/byteorder/ is widespread), among other things
I think it's more immediately clear when Rust code is non portable too. It's not uncommon for random C code to be plagued with undocumented portability issues (and as such, you can't assume that code is portable without some inspection), but unportable Rust code may fail to build on unsupported platforms, which is an excellent idea
Most people just don't care and can't be bothered to spend time making sure code is "endian portable".
Couldn't care less if it is easier to "read in crash dumps" TBH.
I don't even write server code to be portable to anything other than x86_64 or lately just use avx512 without any fallback since it is not needed in practice.
I'm not doing anything people care about probably but I imagine it is a similar feeling for people that do.
I would rather have small software that compiles fast than to add 50 #ifdef into it and make it burn my eyes, and spend time thinking "but would this work in big endian"
No, BE is logical, but LE is efficient (for machines).
The use of automatic computers has forced a transition from the use of arbitrary conventions that did not have any logical motivation to the most efficient methods of data representation, like binary numbers in little-endian format.
Little-endian is more efficient even when you compute by pen on paper, if it feels awkward that is just because you were taught differently as a child.
There are special circumstances when a big-endian representation is the right choice, e.g. when you interpret a bit string as a binary polynomial, in order to implement an error-detection code with a CRC. However, for general-purpose numbers, little-endian is the optimum choice.
LE is logical which is also why it is more efficient and more intuitive for humans once they get past “how we write numbers with a pencil”.
Edit: switched example to hex
Edit2: actually this is still slightly out of whack, but I don't feel like switching to binary so take it as a loose representation rather than literal
But only because when they dump memory, they start with the lowest address, lol.
Why don't these people reverse numberlines and cartesian coordinate systems while they're at it?
> It is usually easy to write code that is endian-safe. Any code that is not endian-safe is poorly written and harder to maintain at best, and possibly obscuring security bugs at worst. Any project maintainer should be jumping for joy when they receive a patch adding a big-endian port of their project, especially if it includes reports that tests pass and the software works. That is the sign of a codebase that has a level of sanity that should not be noteworthy, yet is.
And every single sentence is false.
The tower collapses once you remove any of the bases, let alone all of them.
Every feature has a cost and port to a different architecture has a huge cost in ongoing maintenance and testing.
This is open source. The maintainer isn’t refusing a port. The maintainer is refusing to accept being a maintainer for that port.
A person is always free to fork the open source project and maintain the port themselves as a fork.
The author of the 'port' probably doesn't know your whole codebase like you, so they are going to need help to get their code polished and merged.
For endian issues, the bugs are often subtle and can occur in strange places (it's hard to grep for 'someone somewhere made an endian assumption'), so you often get dragged into debugging.
Now let's imagine we get everything working, CI set up, I make a PR which breaks the big-endian build. My options are:
1) Start fixing endian bugs myself -- I have other stuff to do!
2) Wait for my 'endian maintainer' to find and fix the bug -- might take weeks, they have other stuff to do!
3) Just disable the endian tests in CI, eventually someone will come complain, maybe a debian packager.
At the end of the day I have finite hours on this earth, and there are just so few big endian users -- I often think there are more packagers who want to make software work on their machine in a kind of 'pokemon-style gotta catch em all', than actual users.
There are new users asking how to get Raspberry Pis into aarch64be mode in the Gentoo Arm project channels. There are thousands and thousands of Power Macs. SPARC servers with ridiculous amounts of cores and computer power are super cheap on eBay because Oracle ended support for them - and this is a great way to get a huge thread count cheap, if your software actually runs on it.
Make the BE CI optional if you need to. That way, the maintainer has time to find and fix it, and you can still merge other changes while it runs. What binutils did was have the BE CI run separately and specifically ping the BE maintainers - that way, they know the build's failing, and no one else is bothered with it.
Someone who has a computer that my software can't run on isn't in my community. If they really want to use the software, they have the option of: 1) get a different computer, or 2) maintain their own custom-special port of my software forever.
In other words, they have to JOIN the community if the want the BENEFITS of the community. It's not my job to extend my community to encompass every possible use case and hardware platform.
If hex editors were mirrored both left to right and right to left, would it be easier to read little endian dumps?
-e little-endian dump (incompatible with -ps,-i,-r).This is just so fundamentally wrong that it makes the whole rest of TFA highly suspect (and yes, most of the rest of it is also pretty wrong).
I did however learn a lot googling some of the terms they dropped and finding out things like PowerPC architecture getting and update as recently as 2025.
Several of their references I knew from my first tech leads mentioning their own early career. I am surprised at how much still has active development.
Linus Torvalds disagrees. Vehemently.
https://www.phoronix.com/news/Torvalds-No-RISC-V-BE
> For those who don’t know, endianness is simply how the computer stores numbers. Big endian systems store numbers the way us humans do: the largest number is written first.
Really, what's first? You're so keen on having the big end first, but when it comes to looking at memory, you look... starting at the little end of memory first??? What's up with that?
> I happen to prefer big endian systems in my own development life because they are easier for me to work with, especially reading crash dumps.
It always comes back to this. But that's not a good rationale for either the inconsistency of mixed-endianness where the least significant bit is zero but the most significant byte is zero, or true big endianness, where the least significant bit of a number might be a bit numbered 7 or numbered 15, or even 31 or 63, depending on what size integer it is.
> (Porting to different endianness can help catch obscure bugs.)
Yeah, I'm sure using 9 bit bytes would catch bugs, too, but nobody does that either.
depending on what size integer it is
That's the worst part about BE: values that have a size-dependent term in them, in addition to a subtraction. 2^n vs. 2^(l-n) and 256^N vs 256^(L-N).
According to Linus, BE has been "effectively dead" for at least a decade: https://news.ycombinator.com/item?id=9451284
The author betrays their own point with the anecdote about 586 support: they had tests, the tests passed, but the emulator was buggy, masking the issue. Frankly, if you're the Linux kernel and nobody has the hardware to run the tests on an actual device, it says a lot. But it also shows that qemu is struggling to make it work if the emulation isn't working as it should. How is someone who runs a small project supposed to debug a BE issue when you might have to debug the emulator when a user report comes in?
For me, I'll always welcome folks engaging with my work. But I'll be hesitant to take on maintenance of anything that takes my attention away from delivering value to the overwhelming majority of my users, especially if the value of the effort disappears over time (e.g., because nobody is making those CPUs anymore).
I tend to take another view point (while I understand yours) -- if it's not tested, it doesn't work. And nowadays it's really hard to test big-endian code. I don't have one, I find running different-endian software in QEMU really annoying and difficult.
The article touches on the 32/64 bit split. A lot of the code I write nowadays doesn't run on 32 bit systems, not because it uses a lot of RAM, but because having an actually usable 64-bit address range enables you to write programs that you couldn't on 32 bit.
If you want to write code that works on big endian systems, systems where pointers aren't integers or bytes aren't 8 bits, all the power to you. I'm happy to pretend big endian is not a thing and focus my limited manpower on the hardware that my program will run on.
Obviously the author was trying to just give a quick example to aid visualization, but here's some nitpicking: I can probably come up with at least IV writing systems used by humans that don't use "big endian" for numbers. Or either, really.
Examples: Tally marks, Ancient Egyptian numerals, Hebrew and Attic numerals, and obviously Roman numerals.
Also lots languages in written form order words somewhat... randomly (French, Danish, old English, ...).
The earlier system would write VIIII instead of IX.
With the original Roman numerals, the order of writing was completely irrelevant, because all parts were added and addition is comutative, so VIIII is the same as IIIIV or IIIVI.
Even in the later variant of Roman numerals, you can change the order of many symbols without changing the value.
https://commandcenter.blogspot.com/2012/04/byte-order-fallac...
So in C and the like one uses "unsigned" regardless if bit strings or non-negative numbers are needed.
Because no explicit conversions between bit strings and numeric types are used, it is frequent to have expressions where a certain endianness of the numbers is assumed implicitly.
This is the most frequent source of bugs that manifest when a program is run on a machine with an opposite endianness than assumed in the program.