C library functions are always like: "SYNOPSIS. This function converts foos into bars depending on the user locale. ARGUMENTS. src and dest pointers must be distinct; it is undefined behavior if they are not QPU-aligned. RETURN VALUE. Returns the number of foos converted. A zero value indicates failure, or that zero foos were converted. A negative value indicates that the final foo was only partially converted (function got tired). Check this global variable to find out why."
@typeswitch it sounds bad BUT you can target this code to not work on multiple platforms in multiple distinct ways
@typeswitch function got tired? more like "function got distracted by other things" according to how Unix syscalls were designed
@niconiconi
what if
kernel with ADHD
@typeswitch

@vftdan Well, then you'll have syscalls that can fail with ESQUIRREL.

@niconiconi @typeswitch

@typeswitch @thephd You forgot "flags is a bit mask of 22 bits some of which can be used together and some of which can not which make this function do totally different things"
@malwareminigun @typeswitch @thephd In other words, a model of "control coupling".
WideCharToMultiByte function (stringapiset.h) - Win32 apps

Maps a UTF-16 (wide character) string to a new character string.

@malwareminigun @typeswitch @thephd The beloved `dwFlags` parameter. These two gems on that page, are just 😗:

The function performs more quickly when none of these flags is set.

If all three values are not provided, some results will be missing.

@malwareminigun @smurthys @typeswitch @thephd the win32 is pretty great, the size of it all means it contains just about every API design issue one can think of, now, in hindsight 😀

I do actually like it overall though

@Paxxi I didn't intend to rip on Win32 specifically here; lots of C APIs are horrible. And I'll take a lot of these to one fork(). An API that looks basic but has far-reaching implications, makes accurate memory use tracking impossible, and generally creates cross cutting costs against the whole system. Whereas these examples are contained to only their immediate callers.
@malwareminigun I totally agree, and as I said I generally like the win32 api 😀
@malwareminigun @typeswitch @thephd a personal favorite is "given this flag, the type of parameter 3 changes from T* to T**"
@typeswitch also the flags argument that is explained in the man page for a completely different function :')
@typeswitch Actual comment from a C library I'm working on.

I'm not a C programmer usually, but it seems I've fallen into the same trap.

EDIT: Alt-text
@Ollie @typeswitch I don't entirely get what you're saying but I hope it's not smelly in terms of strict aliasing.
@lizzy @typeswitch It was a toy project to analyze random floating point values for their binary data.

It was mostly to learn how the data type worked. I even had a bit of the code that could (albeitly naively) determine the largest value the fractional part of the number could still be accurately represented.
@lizzy @typeswitch so like if you had a number like 0.1 it would be able to tell you the largest floating point number that could still handle a precision in the tenths place.
@lizzy @typeswitch it is very terrible code, with separate function paths to handle 32-bit and 64-bit floats.

I know there has to be a better way to handle that without hard-coding separate functions for separate types in C but I couldn't be bothered for something that would never be used in production and as someone who knows very little C.
@lizzy @typeswitch

github.com/Ollie-Branch/float-shredder/tree/809681101ecbdf735ba69530cfade5ce1f82268e

Why am I trying to describe how bad it is when you could just read the code lol.
GitHub - Ollie-Branch/float-shredder at 809681101ecbdf735ba69530cfade5ce1f82268e

[WIP] A C/C++ header only library to eviscerate your floats in novel and grotesque ways - GitHub - Ollie-Branch/float-shredder at 809681101ecbdf735ba69530cfade5ce1f82268e

GitHub

@Ollie @typeswitch yea, this breaks static aliasing pretty badly - it’s undefined behavior. instead what you’re allowed to do is cast to char / unsigned char or simply memcpy it (recommended here):

uint32_t output; memcpy(&output, &input_float, sizeof(input_float)); return output;
@Ollie @typeswitch the thing about memcpy is that it conceptually accesses both source and destination as unsigned char array, which makes it legal
@lizzy @typeswitch honestly why didn't I think to do it that way over whatever hack fuck shit I implemented.
@Ollie @typeswitch it's a common misconception. it's generally not allowed to cast a pointer to something to a pointer of a different type. exceptions being if one of them is char* / unsigned char*, or obviously void* is okay because you can't access that directly anyway. other exceptions include stuff like casting a pointer to a struct to a pointer of the type of its first field etc.
@Ollie @typeswitch basically, this exists so that compilers can optimize better by automatically knowing that two pointers don't overlap if they belong to different types. for example they can then cache certain values and registers and don't have to update them even when you write to a different pointer.

rust has instead solved this with the mutability XOR aliasing rule (every piece of data has either 1 mutable reference or N immutable references), which prevents any mutable access while the thing is aliased in a different way. this means rust can do it even more generally, even for things with the same type or u8 and the annoying type aliasing rule goes away
@typeswitch

C library functions are always like: "SYNOPSIS. This function converts  into  depending on the user locale. ARGUMENTS. src and dest pointers must be distinct; it is undefined behavior if they are not QPU-aligned. RETURN VALUE. Returns the number of  converted. A zero value indicates failure, or that zero  were converted. A negative value indicates that the final  was only partially converted (function got tired). Check this global variable to find out why."

Much better.

  
@typeswitch I build up speed for 12 hours to align my pointers
@typeswitch Honestly I rather have this than some doxygen badly rendering on mobile, saying things like "Factory for ElementManager" for classes named "ElementManagerFactory" as documentation to figure out why my application segfaults again
@typeswitch ERRORS. EUNRDBL can occur if any of the following five conditions occur:
@[email protected] @typeswitch deprecated for being unsafe, no replacement
@natty @typeswitch in 2002, Linus Torvalds called this flag "probably designed by a deranged monkey on some serious mind-controlling substances." Unfortunately, it is the best way to achieve what you want to do.
@astrid @typeswitch Only five? That's child's play.
@astrid @typeswitch EUNRDBL is the sound I make in panic if I try to breathe and drink at the same time
@typeswitch Programmer trying to figure out how to use the function in a secure manner…

@typeswitch Thread safety: async-signal-dangerous.

If you're writing a library, forget about using this, there's no way to coordinate with the other potential callers.

@typeswitch @whitequark that only sounds like a C function with a man page. You very rarely get documentation that good in your average header file.
@typeswitch @ShinyQuagsire I still can't believe memfrob is the name of a real function in glibc. Also strfry.
@typeswitch “argument #4 is reserved for future use, setting it to anything other than NULL is considered a programmer error”
@typeswitch
That's almost literally the documentation for sprintf!
@typeswitch the description for string comparison functions drives me absolutely insane. Need a doctorate in deciphering obtuse nerd-speak
@typeswitch well of course it has to be QPU-aligned. Otherwise you'll fall through the floor. Retry with a bit more speed.