rainwarrior wrote:Similarly, the result of malloc() is usually always aligned to 16-bytes or some other size so that it can be safely used with any primitive types the platform requires alignment for. (There are compiler-specific extensions to add alignment requirements to types/structs as well.)
And if it's not implied or apparent to readers: this details of how this is accomplished (re: dynamic memory allocation) is complicated, compounded with mass variances between implementations (GNU libc vs. uClibc vs. musl vs. FreeBSD 9.x and earlier libc (uses its own implementation)
vs. FreeBSD 10.x later libc (uses jemalloc)
. Functions like aligned_alloc()
(and non-standard MALLOCX_ALIGN()
for jemalloc) can guarantee alignment on some other boundary of your choice.
Off-topic but semi-relevant: what's often unknown to general programmers is that many malloc implementations actually allocate more than what you ask for (ex. malloc(32)
will probably allocate 4096 bytes internally, but may pick something larger or smaller depending on all sorts of logic and heuristics), since the malloc implementation itself manages pages into different categories/sizings to greatly minimise memory fragmentation. I believe several implementations also care deeply about cache line size. For jemalloc, the implementation is actually described in the IMPLEMENTATION NOTES section of the man page I linked, ditto with older FreeBSD's libc.
As for compilers (not libc/malloc!) deciding what to pad: depends on compiler. This is especially a problem for struct
s (it's one of the most commonly-discussed topics). rainwarrior covered that most of its controlled with #pragma
, varying per compiler. Usually you'll find someone using something like __attribute__((aligned(XXX),packed))
. Wikipedia has an article
on the general matter of data structure alignment complexities with lots of C details. Eric Raymond also has a very detailed page
on the matter.
Today's C compilers are often focused on portability (which was not a focus of C when originally created in the 70s, but within 4-5 years became a serious focal point that remains today), so there's that trade off too.
It sounds to me like folks complaining about lack of C compiler essentially are saying "assembly is fine but it takes a long time to write + is more tedious to deal with than something like C". And that's very true! Reading between the lines, to me that means an intermediary PL that is 65xxx-series friendly (re: limited registers, etc.), but not as tie-consuming as assembly, would benefit the masses. What's funny about that is in the 70s and early 80s, there were some PLs invented with that sort of thing in mind (given the design of CPUs and systems during that era)... all of which by today have (generally) fallen out of favour in exchange for more commonplace PLs... C being one such PL. :-)
There really isn't something that fills the gap between C and assembly, and definitely even more so when taking the limits of the 65xxx architecture into consideration. As such, the best two things we have right now are: a) cc65, which has had some games written in it (with assembly being required for important bits), and is 6502-centric (read: does not benefit from additional 65816 instructions, addressing modes, and register sizes), and b) Toshi Morita's lcc816, which in its current form won't emit 65816 assembly that's compatible with any present-day 65816 cross assembler.
If I could magically wave my arms and make something happen, it would be to fix/improve 65816 support for cc65 and ca65 (the assembler, which does not cater well to 65816 in its present form (I've discussed this before)), and tell people "if you know C, use this, but you are expected to also know 65816". If said magic happened, I think Stef would probably put in the time/effort to do the dev env/lib/framework to make development easier for folks. But I'm not a magic wizard. IMO, the effort to make TM's lcc816 work with some present-day 65816 cross assemblers (ex. WLA-DX, etc.) would probably take less effort, *unless* the person doing the work is more familiar with compiler internals and compiler theory.
And none of this even begins to touch base on graphical or audio tools. That's a whole other world of hurt that, much like assemblers, had better support back in the snesdev heyday of the early 90s. I could talk about that for hours but it's way off topic. I do remember one thing, though: in the early 90s, there were lots of people who got interested in snesdev, did little doo-dads, then disappeared into the void once the subject of SPC700/audio/music came up. I think the SNES happens to be an incredibly complicated console, probably overly so, but in a lot of ways I still think it feels way, *way* easier to program/work on than the NES. I guess because I started with the SNES and later did NES stuff makes me a bit biased towards the 16-bit console.