Live data from Hacker News

How SerenityOS declares ssize_t

awesomekling.github.io

81–90 of 95 posts

Re: How SerenityOS declares ssize_t

#81
post #49

I would do it like this: #if SIZEOF_SIZE_T == 8 typedef int64_t ssize_t #elif SIZEOF_SIZE_T == 4 typedef int32_t ssize_t #elif SIZEOF_SIZE_T == 2 // LOL typedef int16_t ssize_t #else #error port me! #endif SIZEOF_SIZE_T can be obtained using a script which compiles a test program without executing it. Over they years I used more than one approach, settling on this one: https://www.kylheku.com/cgit/txr/tree/configure?…

> #elif SIZEOF_SIZE_T == 2 // LOL Fun fact - for a while, this was true for the third most popular processor architecture in the world, one that most people haven't heard of. CSR (the bluetooth chip maker) was originally a spin-out from Cambridge Consultants, and their chips were for years based on a Cambridge Consultants processer design called XAP. As CSR had made billions of devices, XAP was likely right up there…

What’s also interesting was that the processor was actually a 32 bit processor iirc (at least the later ones). The 16 bit variant is purely the VM mode they run “application” code on which emulates the environment of an old CPU (my guess anyway - not sure why the VM was limited to 16bits).

The Kalimba was equally weird with sizeof(int) = 1 being 24 bit and sizeof (long) was 48bit. I ported an ECDSA library to it for Pixel Buds 1 because the XAP was too slow. It was really really hard to get that to work properly and writing a simulated environment to make sure I emulated the math correctly with masking and whatnot.

It was such an annoying architecture to work with that all the senior SW leads for Pixel Buds fought extra hard to avoid Qualcomm’s solution. Their evolution for the next set of chips to compete with Apple’s W1 saw them go down a weird path where they doubled down on getting rid of GCC and instead using their home grown compiler (none of their shit ran natively on Linux not Mac) and similarly weird architecture decisions (forget all the details now). Our job was made easier in that they couldn’t actually deliver a W1 competitor. Their best was exposing each bud as a separate device which would have been a terrible experience and they could only improve that experience for Android if we mainlined their weird decisions into Android (sorry - no). By comparison BESTech delivered a proper competitor design to the W1 (transparent sniffing and hand off) and their SW architecture was totally sane (ARM chip + gcc for sure + FreeRTOS if I recall correctly). Much better partners than Qualcomm.

Re: How SerenityOS declares ssize_t

#82

Redefining a keyword via macro violates the C++ standard: > Nor shall such a translation unit define macros for names lexically identical to keywords. https://stackoverflow.com/questions/9109377/is-it-legal-to-r...

Lucky for them, it's a fully custom OS that doesn't follow the standard :)

Re: How SerenityOS declares ssize_t

#83

Redefining a keyword via macro violates the C++ standard: > Nor shall such a translation unit define macros for names lexically identical to keywords. https://stackoverflow.com/questions/9109377/is-it-legal-to-r...

Lucky for them, it's a fully custom OS that doesn't follow the standard :)

They don't make the compiler. GCC in very many places substitutes standard library names with intrinsics for the purposes of optimization or static analysis. I'm not aware of it doing so for ssize, but in principle this is a bad idea.

Re: How SerenityOS declares ssize_t

#84
post #57

this locks you into the compiler. i used to do "cute" tricks like this. then i learned better. always write the least mysterious code unless you have a good reason...

Actually both GCC and Clang have this feature (so does Circle), and uhh there are plenty of other indispensable features that lock you into those. You need statement expressions and inline assembly to write this kind of software.

Re: How SerenityOS declares ssize_t

#85
post #49

Earlier quoted context omitted.

> #elif SIZEOF_SIZE_T == 2 // LOL Fun fact - for a while, this was true for the third most popular processor architecture in the world, one that most people haven't heard of. CSR (the bluetooth chip maker) was originally a spin-out from Cambridge Consultants, and their chips were for years based on a Cambridge Consultants processer design called XAP. As CSR had made billions of devices, XAP was likely right up there…

What’s also interesting was that the processor was actually a 32 bit processor iirc (at least the later ones). The 16 bit variant is purely the VM mode they run “application” code on which emulates the environment of an old CPU (my guess anyway - not sure why the VM was limited to 16bits). The Kalimba was equally weird with sizeof(int) = 1 being 24 bit and sizeof (long) was 48bit. I ported an ECDSA library to it for…

> What’s also interesting was that the processor was actually a 32 bit processor iirc (at least the later ones). The 16 bit variant is purely the VM mode they run “application” code on which emulates the environment of an old CPU (my guess anyway - not sure why the VM was limited to 16bits).

I was writing code natively for the processor - it was a XAP5 and natively 16 bit. Possibly CSR later moved to XAP6 (which was 32-bit) and kept application code portable using the VM.

Kalimba was my first experience writing hand-coded assembly - I was implementing sample rate conversion for a hearing aid manufacturer. It was good fun - a dedicated multiply accumulate that meant you could do filtering in a single instruction per sample.

Re: How SerenityOS declares ssize_t

#86
post #73

Earlier quoted context omitted.

That's interesting. I didn't actually know the definition of uintXX_t. I was actually doing this with C90 most of the time, and using types we had defined (rather than from stdint.h). Sounds like they were more equivalent to int_leastXX_t. I realise know when I've previously written the above examples I've done it was basic types, so sizeof(char), sizeof(int) etc.. Sounds like it would be more correct as well!

Ah yes, having char and short etc be the same size makes a lot more sense, while still being a massive trap for young players.

[deleted]

Re: How SerenityOS declares ssize_t

#87
post #73

Earlier quoted context omitted.

> sizeof(uint16_t) == 1 > This is all completely legal according to the C standard. Is it? I don't have access to the standard, but from secondary sources[1] it seems not? unsigned integer type with width of exactly 8, 16, 32 and 64 bits respectively (provided if and only if the implementation directly supports the type) If it is, it kinda defeats the whole purpose of uint16_t and friends. [1]: https://en.cppreferenc…

That's interesting. I didn't actually know the definition of uintXX_t. I was actually doing this with C90 most of the time, and using types we had defined (rather than from stdint.h). Sounds like they were more equivalent to int_leastXX_t. I realise know when I've previously written the above examples I've done it was basic types, so sizeof(char), sizeof(int) etc.. Sounds like it would be more correct as well!

Yeah, checking C11 (FCD), “The typedef name uintN_t designates an unsigned integer type with width N and no padding bits.” My reading is that they should not have defined `uint8_t`. Probably they did so pragmatically (and maybe optionally) because so much code writes `intN_t` when they mean `int_leastN_t`, with 8 in particular. I don't think I've ever actually seen the `_least` or `_fast` versions used in real life.

(I've worked with multiple processors with MAU>8; I recall at least one with 24-bit ‘bytes’, though I've forgotten what domain drove that.)

Re: How SerenityOS declares ssize_t

#88
post #85

Earlier quoted context omitted.

What’s also interesting was that the processor was actually a 32 bit processor iirc (at least the later ones). The 16 bit variant is purely the VM mode they run “application” code on which emulates the environment of an old CPU (my guess anyway - not sure why the VM was limited to 16bits). The Kalimba was equally weird with sizeof(int) = 1 being 24 bit and sizeof (long) was 48bit. I ported an ECDSA library to it for…

> What’s also interesting was that the processor was actually a 32 bit processor iirc (at least the later ones). The 16 bit variant is purely the VM mode they run “application” code on which emulates the environment of an old CPU (my guess anyway - not sure why the VM was limited to 16bits). I was writing code natively for the processor - it was a XAP5 and natively 16 bit. Possibly CSR later moved to XAP6 (which was…

Yeah maybe it was the XAP6 (CSR8675 if I recall correctly the exact model number).

For the kalimba I just used the Qualcomm C compiler. There may have been some assembly for audio related things although I can’t recall. It was mostly C code though I think.

That’s actually what they tried to do for the new chips if I recall correctly - they put Kalimba everywhere. I was like - wtf are you doing Qualcomm.

Re: How SerenityOS declares ssize_t

#89

"__SIZE_TYPE__" is a builtin symbol in the preprocessor, seriously?

    echo __SIZE_TYPE__ | cpp -
    # 1 ""
    # 1 ""
    # 1 ""
    # 31 ""
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 32 "" 2
    # 1 ""
    long unsigned int
Okay, so it's defined in a file apparently. But why is that file automatically included in every program, and not the more usual type definitions? And is there really no better way to define "an integer the size of a pointer" than by going through this rat's nest of text substitutions?

The C language seems almost designed on purpose to maximize uglyness. It is called "portable assembly language", but even in this day and age when there are only two or three relevant processor architectures, which have been largely designed around being able to run C code efficiently (to the detriment of everything else), it falls short of that.

It is only portable at all because of include files that are included from other files, containing __MACROS__ calling on __OTHER__MACRO_S___ to the n-th degree.

The most advanced compiler algorithms are then applied to the problem of transforming the resulting ((void *)(__pile_of(cr*p))()) back into machine code that is at least not completely terrible. Follow every obscure rule of the standard, and they might be so nice not to remove your carefully written null pointer check in the process!

And people worship this uglyness and needless complexity, even as it strangles the life out of every other technology like a cancer that has been growing for 50 years. Professionals and hobbyists both, they celebrate how clever they are, being able to work around its deficiencies, think that they are dealing with the fundamentals of computer science rather than the grotesque evolution of an operating system originally written to typeset documents and play SpaceWar.

Just once I'd like to see a new operating system - better yet, a new CPU! - that is not based on C and UNIX, one that is outright hostile to them at every level of abstraction. Not a single line of C code anywhere, different calling convention, different filesystem, user interface, networking etc.

Re: How SerenityOS declares ssize_t

#90
post #55
post #32

Earlier quoted context omitted.

It's a philosophy thing. There are plenty of languages that just solve for flat Von Neumann memory models. In the past, that did not describe all machines -- e.g. the pre-standard Borland C/C++ compilers for x86 real mode that used 32-bit ptrdiff_t and 16-bit size_t (which doesn't count as an answer because they were pre-standard in so many ways). In the future, it may or may not describe all machines -- it's possibl…

C23 follows C++ in requiring signed integers to have two's complement representation. I think by this point it's pretty much settled that it's the "optimal" way to implement signed integers. Now if we change to non-binary architectures (or something radically different) things might change, but at that point quite a lot of the C standard will have to be thrown out as well.

I /mostly/ agree -- it's hard for me to think of a modern or future platform that would use ones complement integers... with one possible exception. Integers represented on top of IEEE floating point are inherently ones-complement (sign+magnitude), and I can definitely imagine potential future platforms that use 64-bit floats as their primary primitive, restricting them to integer representations for certain tasks. Thinking of designing something like a DSP-focused microcontroller in a world where onboard SRAM can significantly exceed 4GB, and where a desire for C compatibility and occasional tasks make it worthwhile to support function and data pointers, but supporting 53-bit pointers in a float ends up simpler than adding a 64-bit integer ALU that would rarely be used. In this case the associated types (ptrdiff_t, for example) might end up as 53-bit ones-complement integers stored in floats.
Post reply on HN