Skip to content

Comment on A Special Kind of Hell: intmax_t in C and C++ (2020)

Comments

The problem isn't "intmax_t". The problem is "int".

If you have an ABI, you need to put an explicit size and signedness on every parameter and return value. Period. No excuses.

No "int". No "unsigned int". If I'm being really pedantic, don't even use "char".

It should be "int32_t", "uint32_t", and "uint8_t".

Every time I see objections, it's always someone who wants to use some weird 16-bit architecture. The problem is that those libraries probably won't work anyhow since nobody tests their libraries on anything other than x86 and maybe Arm. If your "int" is 16 bits, you're likely to have a broken library anyway.

There are a few variable size types that make sense in an ABI. Like `size_t` and `(u)intptr_t`.

If I'm being really pedantic, don't even use "char".

Careful about that one. I believe `uint8_t` isn't required to be a character type, which has implications for type based aliasing.

Careful about that one. I believe `uint8_t` isn't required to be a character type, which has implications for type based aliasing.

The fact that every single compiler typedefs "uint8_t" and "unsigned char" and yet that isn't guaranteed by the standard is the kind of thing that just makes you want to cry.

I'm actually genuinely curious about this: people talk about the possibility of existence, but I haven't seen anybody point to an actual compiler that implements uint8_t as an extended numeric type rather than being an equivalent typedef to "unsigned char". Is there a compiler that really does this?

> The fact that every single compiler typedefs "uint8_t" and "unsigned char" [...] and yet that isn't guaranteed by the standard

They don't. The standard is right on this. It's supposed to let authors know what can be relied on portably on real C/C++ systems in use. (Targets where char is not even 8 bits might make you cry even more, but I think those are legitimately obscure now.)

> Is there a compiler that really does this?

Here's a popular one with hobbyists in 2022. The definition of uint8_t in the Arduino system header files is not "unsigned char". I have seen this definition used elsewhere too:

  typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
https://forum.arduino.cc/t/definition-of-uint8_t/177947 https://forum.arduino.cc/t/mismatching-integer-type-definiti...

Except that __attribute__((__mode__(__QI__))) makes that effectively equivalent to "unsigned char".

From https://groups.google.com/g/comp.lang.c/c/sE6I4sgGyPs

A few tests on generated code, however, suggest that gcc treats these exactly as signed char and unsigned char, both in how the react to _Generic and in how the compiler handles them for alias analysis.

So, that means that there are currently zero existing compilers that treat uint8_t differently from unsigned char.

Pretty sure I remember a GCC bug that amounted to uint8_t behaving differently to unsigned char wrt aliasing. It's the sort of thing I'd expect clang to do too.

Personal opinion, 'int' is way above NULL as a bad idea.

"int" wasn't a bad idea "back in the day".

Different architectures had all manner of different "native" sizes. 8-bit micros were still relatively expensive even up through mid-1980s. The 80286, for example, was 16-bit and went away only in the early 1990s. IBM AS/400s were still 48-bits through the mid-1990s. Apple was still dealing with non-32 bit clean applications in the mid 90s. Linux running on Alpha was still cleaning up x86-isms in mid 1990s.

C99 finally introduced "stdint.h". By the mid-2000s, everything had converged to 32-bit (or 64-bit).

C11 should have deprecated "int" so that compilers could throw warnings on it. But, then, we still haven't removed K&R signatures from the C standards, so here we are.

IIRC K&R signatures are out in C23.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.