On Wed, Aug 24, 2022 at 11:41 PM Florian Weimer <fweimer@xxxxxxxxxx> wrote: > > The justifications brought forward are just regurgitating previous > misinformation. If you do that, it's hard to take you seriously. Pot, meet kettle. > There is actually a good reason for using __u64: it's always based on > long long, so the format strings are no longer architecture-specific, [..] That's a small detail that yes, we've tried to avoid the absolute humongous mess that the C standard library has with their horrendous 'PRId*' mess, but honestly, it's just a tiny detail. The real issue is that we want to be able to control our own types, and our own names, and in the process have sometimes been able to standardize on types that makes it easier to just not have to deal with "oh, somebody picked 'int' on this architecture, and 'long' on this other, and they are both 32-bit types". We still have to deal with that for '[s]size_t', but that's such a standard legacy type that thankfully we have the whole '%zu/%zd' thing for that. And yes, sometimes we screw up even *though* we were the ones that picked the types, and we've had pointless differences where '__u64' could be 'unsigned long' on a 64-bit architecture, and 'unsigned long long' on a 32-bit one, and then we were able to fix our own little broken type system exactly because it was *OUR* little type system. So you are correct that then in the specific case of '__u64' we have been able to simply just standardize on 'unsigned long long' and make printf strings simpler. But you are wrong to think that that is somehow a special thing. It's not. It's very much all the same thing: we have types *we* control, and thanks to that we can do them the way *we* need them done, and can fix them when we made a silly mistake. In other words, it's the whole *point* of not ever using 'stdint.h' at all for those things. (It's also about avoiding the kinds of unholy things that happen in system header files. Have you ever *looked* at them? Christ. The amount of absolute crap you get from including <stdint.h> in user space is scary) > You cannot avoid using certain ISO C names with current GCC or Clang, > however hard you try. You are now the one who is regurgitating complete mis-information. You do it so prettily, and with such weasel-wording, that I know you must be knowingly threading that fine line between "actively misleading" but trying to avoid "outright lying".. You say "certain ISO C names" to try to make it sound as if this was at all relevant to things like "uint32_t" and friends. But deep down, you know you're basically lying by omission. Because it's true that we have to know and care about things like 'size_t', which comes up for all the basic string.h functions. So yes, we have a very small set of types that we make sure matches the compiler notion of said types, and we carefully use things like typedef __kernel_ulong_t __kernel_size_t; and then we have our own 'stdarg.h which uses typedef __builtin_va_list va_list; that is explicitly the one that the compiler exposes with those double underscores exactly because even the compiler can't expose the "standard" name due to namespace issues. And no, NONE OF THOSE ARE USABLE IN THE UAPI HEADERS! And equally importantly, none of those have *anything* to do with the 'uint32_t' kind of names. The fact that yes, we care about what the compiler thinks "size_t" is (because we do want the compiler to do memset() for us) has absolutely *NOTHING* to do with uint32_t and <stdint.h>. And I'm pretty sure you knew that, but you tried to make it sound like they were somehow all in the same boat. And yes, some drivers tend to actually use 'uint32_t' in the kernel, and we allow it, but they cannot be used by user interfaces. So a uapi file really *really* shouldn't ever use them. And no, we don't use "-ffreestanding" and friends - we actually have occasionally wanted and tried to do so just to make the boundary lines clearer, but then that will make gcc no longer do sane things for 'memcpy()'' and friends, so it's kind of a balancing act. > <stdarg.h>, <stddef.h>, <stdint.h> are compiler-provided headers that > are designed to be safe to use for bare-metal contexts (like in > kernels). Avoiding them is not necessary per se. We explicitly avoid them all. We historically used stdarg.h and stddef.h (but never stdint.h - there's absolutely _zero_ upside), but it was always a slight pain. So we simply bake our own, exactly because it's simply less painful than having to deal with possible system-provided ones. People do odd compiler things with host compilers, bad or odd installations of cross-build environments, it's just not worth the pain to deal with the "system header files" when they just don't provide any real value. Linus