Earlier quoted context omitted.
If you do "for (int i = 0; i While two's complement signed rollover can be pretty useful, in 99% of cases you don't need it, and casting to unsigned for the 1% is a worthwhile sacrifice for the better optimizations for the common case, and it'll be pretty clear when you want wrapping or not (and sanitizers will be able to keep reporting signed overflow as errors without false positives).
No, my 'intent' is to get: error: signed integer variable used as array index (-Wsigned-index) `int i`: should be `size_t i` error: comparison of signed to unsigned integer (-Wsigned-comparison) `i Scare quotes on "intent", because I don't write (that particular kind of) obviously broken code in the first place, but the upshot is that i and len both need to be size_t, and anything that lets the compiler obscure that…
C23 Implications for C Libraries
121–130 of 135 posts
Re: C23 Implications for C Libraries
#122Earlier quoted context omitted.
If you mean MVSC, it never will, because it now supports C11 and C17, minus the optional annexes from C99 that were dropped in C11, and atomics aren't fully supported as well.
I've heard that they are working on C11 atomics, now that the C++ standard includes for compatibility with C.
It was the whole change of management that somehow made them backtrack on that decision.
Re: C23 Implications for C Libraries
#123Earlier quoted context omitted.
Neither. The code wasn't standard C, and it didn't just "happen" to work, either. You probably wouldn't want to build an atomic compare-exchange in standard C, even if it were possible; you find out what the hardware provides and work with that.
> The code wasn't standard C, and it didn't just "happen" to work Thanks, that makes sense. At the risk of sounding pedantic, you did say using nothing but C99 or C90 , implying use of standard features only. > You probably wouldn't want to build an atomic compare-exchange in > standard C, even if it were possible; you find out what the > hardware provides and work with that. Agreed.
bool cmpswap64(uint64_t *location, uint64_t if_old, uint64_t then_new);
Code that relies on the header doesn't have to process anything compiler-specific. FFI could be used to bind to that function from non-C languages.Re: C23 Implications for C Libraries
#124>> One major change in the language is that two’s complement is now mandatory as a representation for signed types. This pleases me greatly. Two's complement won decades ago. This also means they could define integer overflow as 2's complement rollover, which is almost universal but is still considered undefined behavior.
> This also means they could define integer overflow as 2's complement rollover, which is almost universal but is still considered undefined behavior. No, they should not. Integer overflow is in most cases logic error, like division by zero or NULL pointer dereference, so it should stay undefined.
Re: C23 Implications for C Libraries
#125Earlier quoted context omitted.
They could introduce a similar type that is prohibited (checked by the compiler) from occurring in declarations with external linkage (plus some wording regarding casting of data across translation units being undefined behavior for that type). Effectively prohibit it from being used in ABIs. It would then still be useful for intermediate calculations and in macros.
That doesn't work because possibly[2] the most important single use of uintmax_t is the printf specifier "%ju", ie a ABI boundary. Ironically, this is actually one of the only[0] legitimate uses for standard[1] PRI* macros, since that could expand to whichever of "%llu", "%w128u", etc, was appropriate to the caller. 0: And I'm not sure "one of" is actually needed. 1: as opposed to nonstandard ones like PRIu_xlib_atom…
Re: C23 Implications for C Libraries
#126Earlier quoted context omitted.
I don't fully understand the need or benefit of having free_sized() available tbh. Spec says it's functionally equivalent to free(ptr) or undefined: If ptr is a null pointer or the result obtained from a call to malloc, realloc, or calloc, where size size is equal to the requested allocation size, this function is equivalent to free(ptr). Otherwise, the behavior is undefined Even the recommended practice does not rea…
> I don't fully understand the need or benefit of having free_sized() available tbh. It's a performance optimization. Allocator implementations spend quite a lot of time in free() matching the provided pointer to the correct size bucket (as to why they don't have something like a ptr->bucket hash table, IDK, maybe it would consume too much memory overhead particularly for small allocations?). With free_sized() this s…
Re: C23 Implications for C Libraries
#127Earlier quoted context omitted.
> This also means they could define integer overflow as 2's complement rollover, which is almost universal but is still considered undefined behavior. No, they should not. Integer overflow is in most cases logic error, like division by zero or NULL pointer dereference, so it should stay undefined.
That's only true for the relatively recent and generally unhelpful "nasal demons" interpretation of undefined behavior; under the older concept, which is more like "do whatever the sensible thing would be on the target platform", rollover is probably just what you want.
"NOTE: Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (...), to terminating a translation or execution (...)."
> which is more like "do whatever the sensible thing would be on the target platform"
That is a meaning of 'implementation-defined' in C parlance.
Re: C23 Implications for C Libraries
#128Earlier quoted context omitted.
My usages are similar to yours, but new C standards still benefit me because I can opportunistically detect and make use of new features in a configure script. To use my baby as an example: free_sized(void *ptr, size_t alloc_size) is new in C23. I can detect whether or not it's available and use it if so. If it's not available, I can just fall back to free() and get the same semantics, at some performance or safety c…
The free_sized function is kind of a bad example, though. For years to come, using free_sized will break malloc interposition. Interposed mallocs will not support free_sized initially. (It's currently not in jemalloc, tcmalloc, mimalloc as far as I can see.) If we add it to glibc and your application picks it up, calls to free_sized will end up with the glibc allocator even if malloc/free/… have been interposed. Mayb…
We emailed about this a little contemporaneously (thread "Sized deallocation for C", from February), and I think we came to the conclusion that glibc can make interposition work seamlessly even for interposed allocators lacking free_sized, by checking (in glibc's free_sized) if the glibc malloc/calloc/realloc has been called, and redirecting to free if it hasn't. (The poorly-named "Application Life-Cycle" section of the paper).
Re: C23 Implications for C Libraries
#129Earlier quoted context omitted.
That's only true for the relatively recent and generally unhelpful "nasal demons" interpretation of undefined behavior; under the older concept, which is more like "do whatever the sensible thing would be on the target platform", rollover is probably just what you want.
Distinction between undefined, unspecified, and implementation-defined is already in ISO C99 specification and is rather specific: "NOTE: Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (...), to terminating a translation or execution (...)." > which is mor…
Re: C23 Implications for C Libraries
#130Earlier quoted context omitted.
> Who exactly are these new C-standards for? An example: The C11 memory model + + many compilers supporting C11 has/had a positive impact on language runtimes. Portable CAS! > If your team is up-to-date enough to quickly adopt C23, then why not just use Rust or (heaven forbid, C++23)? Another example: If you're programming e.g. non-internet-connected atomic clocks with weather sensors like those produced by La Crosse…
Atomic is one of the few things in C11 I like most. Unfortunately, it is an optional feature along with threading [1]. It is not portable. In the end, I am still using gcc/clang's __sync or __atomic builtins. [1] https://en.wikipedia.org/wiki/C11_(C_standard_revision)#Opti...
Portability isn't binary. It's the result of work being done behind-the-scenes to provide support for a common construct on a variety of hardware and operating systems. It's a spectrum.
GCC certainly is portable, but it doesn't support every ISA and OS. Over time it has even dropped support for several.
Random thoughts since I'm still in the process of waking up…
1. Most of is optional
2. long is 64 bits on Tru64 Unix which is valid under all versions of the standard