Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

When I dealt with this, there were a couple major gotchas:

* Compilers seem to reliably detect byteswap, but are(were) very hit-or-miss with the shift patterns for reading/writing to memory directly, so you still need(ed) an ifdef. I know compilers have improved but there are so many patterns that I'm still paranoid.

* There are a lot of "optimized" headers that actually pessimize by inserting inline assembly that the compiler can't optimize through (in particularly, the compiler can't inline constants and can't choose `movbe` instead of `bswap`), so do not trust any standard API; write your own with memcpy + ifdef'd C-only swapping.

* For speaking wire protocols, generating (struct-based?) code is far better than writing code that mentions offsets directly, which in turn is far better than the `mempcpy`-like code which the link suggests.



C programmers say things like "C is close to the machine"(+) and then have to write a huge elaborate macro in order to fool the compiler into generating a single machine instruction which is the one they actually want.

One of these days I'll write my "actually typesafe portable macro assembler" project. It will be .. opinionated.

(+) which machine, though


> (+) which machine, though

A PDP11. Tbf, for most lower level languages it's fairly close to a pdp 11.


You should give an example of that here: godbolt.org

I have never had to do what you're talking about.


Cannot you just __asm__() things ?


Not portably!

People want to have their cake (not having to think about instruction names, code generation for arithmetic expressions, or register allocation, because those differ per platform) and eat it (generate reasonably predictable machine code for multiple different platforms).

Things like LLVM IR are pretty close, but understandably nobody wants to write IR by hand.


As I mentioned, asm is often a pessimization. GCC has a lot of useful builtins though.


I can't remember the source, but AFAIK packed structs aren't mandated in the specification. It's terrible because a programmer will OFTEN see that result, on any architecture they're familiar with; however it isn't guaranteed to be portable.

One of the top google hits when I searched for 'c packed structs' https://stackoverflow.com/questions/4306186/structure-paddin...


Wow, that SO post is full of very bad answers. Regardless ...

Even ignoring compiler extensions, you don't have to memcpy the struct to the network directly (though this necessarily must be doable safely due to the fact that <net/> headers use it). Instead, define an API that takes loose structs, and have generated code do all the swapping and packing from the struct form to the bytes form.

If you're careful, you might make it such that on common platforms this optimizes into just a memcpy. But if the struct can get inlined this doesn't actually matter.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: