denotational
Missed my favourite one: differences in the memory consistency model.

If you’re using stdatomic and the like correctly, then the library and compiler writers have your back, but if you aren’t (e.g. using relaxed ordering when acquire/release is required), or if you’re rolling your own synchronisation primitives (don’t do this unless you know what you’re doing!), then you’re going to have a bad day.

johnklos
One of the larger problems is purely social. Some people unnecessarily resist the idea that code can run on something other than x86 (and perhaps now Arm).

Interestingly, some apologists say that maintaining portability in code is a hinderance that costs time and money, as though the profit of a company or the productivity of a programmer will be dramatically affected if they need to program without making assumptions about the underlying architecture. In reality, writing without those assumptions usually makes code better, with fewer edge cases.

It'd be nice if people wouldn't go out of their way to fight against portability, but some people do :(

hanikesn
Looks like non 4k page sizes are missing, which tripped out some software running on asahi Linux.
magicalhippo
One I recall, working on a C++ program that we distributed to Windows, Linux and PowerPC OSX at the time, was how some platforms had memory zero-initialized by the OS memory manager, and some didn't.

Our code didn't mean to take advantage of this, but it sometimes meant buggy code would appear fine on one platform as pointers in structures would be zeroed out, but crash on others where they weren't.

As I recall, it was mostly that and the endianess that caused the most grief. Not that there was many issues at all since we used Qt and Boost...

Archit3ch
The fun of discovering size_t is defined differently on Apple Silicon.
AStonesThrow
In my misspent college years, I was coding game servers in C. A new iteration came about, and the project lead had coded it on a VAX/BSD system, where I had no access.

Under whatever C implementation on VAX/BSD, a NULL pointer dereference returned "0". Yep, you read that right. There was no segfault, no error condition, just a simple nul-for-null!

This was all fine and dandy until he handed it over for me to port to SunOS, Ultrix, NeXT Mach BSD, etc. (Interesting times!)

I honestly didn't find a second implementation or architecture where NULL-dereference was OK. Whatever the standards at the time, we were on the cusp of ANSI-compliance and everyone was adopting gcc. Segmentation faults were "handled" by immediately kicking off 1-255 players, and crashing the server. Not a good user experience!

So my first debugging task, and it went on a long time, was to find every pointer dereference (and it was nul-terminated strings) and wrap them in a conditional "if (ptr != NULL) { ... }"

At the time, I had considered it crazy/lazy to omit those in the first place and code on such an assumption. But C was so cozy with the hardware, and we were just kids. And there was the genesis for the cynical expression "All The World's A VAX!"

benchloftbrunch
Something not mentioned is that on Windows `long` is always 32 bits (same size as `int`), even on 64-bit architectures.
malkia
Is it still the case that wasm is still 32-bit?
milabogdanova
[dead]