12 ms·
C23 Implications for C Libraries
- dottedmag 4y agoHah > Extended integer types may be wider than intmax_t
- rwmj 4y agoAlready true in many implementations. The committee is just catching up with reality ;-(
- 4str0n0mer 4y ago
- rwmj 4y agoThe page gives a network error. Edit: Ugh, it needs javascript to render simple HTML.
- turminal 4y agoAnd it's still broken on my phone.
- account42 4y agoThe content seems to be hosted in a GitLab repo with the raw view serving the HTML but with the wrong content type. The JS is there to fix that. Weird setup.
- ainar-g 4y agoIt's especially weird considering that the Markdown file is publicly available: https://icube-forge.unistra.fr/icps/c23-library/-/blob/main/README.md https://icube-forge.unistra.fr/icps/c23-library/-/blob/main/... Raw Markdown, for no-JS readers: https://icube-forge.unistra.fr/icps/c23-library/-/raw/main/README.md https://icube-forge.unistra.fr/icps/c23-library/-/raw/main/R...
- jwilk 4y agoArchived copy that works without JS: https://archive.today/Hz81c https://archive.today/Hz81c
- rurban 4y agoThe last line has a typo: besearch_s => bsearch_s
- GrumpySloth 4y ago> Trigraphs are removed from the language. Finally! My joy knows no bounds.
- turminal 4y agoWhy? They seem pretty harmless, are they difficult to implement?
- merlincorey 4y agoI've only seen them recently in things like the IOCCC. [0] https://www.ioccc.org https://www.ioccc.org
- GrumpySloth 4y agoThey’re not difficult to implement. It’s a sed pass running before any preprocessor or even lexer, which is the horrifying thing. They replace characters in source code, they’re not normal tokens like digraphs. And so e.g. the following program won’t print what a mere mortal would expect: #include <stdio.h> int main() { puts(“What??(Really.)”); } Try running that. Only change the quote marks to the ones on a normal keyboard (I’m on my phone.) Edit: Oh, and remember to compile with -std=c11 e.g. gnu11 has trigraphs disabled by default.
- avar 4y agoThe standard itself has a better example (well, older versions). In C99 it's: printf("Eh???/n"); Which is the same as: printf("Eh?\n"); I.e. the "??/" supplies the "\" to the "n", making it a "\n". I think it's good that they're gone (they were there to support some ancient non-ASCII systems). But it's worth mentioning that the "horrifying" semantics are there so that these trigraphs combine with <s>digraphs</s> (edit: "escape sequences", see downthread) in this way. Otherwise you'd just get: printf("Eh?\\n");
- GrumpySloth 4y agoThis example doesn’t involve digraphs. Trigraphs also preceded digraphs, so their semantics couldn’t have been motivated by digraphs. In fact digraphs were added as a better-thought-out alternative to trigraphs. Digraphs were added in C99, whereas trigraphs were added in C89.
- avar 4y ago"Extended integer types may be wider than intmax_t". I'm sure there's a good reason for this, but it was introduced in C99, which says (in 7.8.1.5): "[intmax_t] designates a signed integer type capable of representing any value of any signed integer type". That was already portable between 16 bit, 32 bit, 64 bit etc. Why is it that just because the compiler supports 128 bit or 256 bit integers that compiling in such a mode doesn't correspondingly update "[u]intmax_t"? The linked page says they 'cannot be "extended integer types" in the sense of C17', but that printf() and scanf() should still support these?
- deleted 4y ago[deleted]
- tpush 4y agoPresumably because the size of intmax_t was set to something specific on its introduction and changing it now would constitute an ABI break most everywhere.
- stephencanon 4y agoThat’s exactly right. On platforms without ABI stability concerns, there’s no issue, but if you can’t change the ABI intmax_t is stuck being what it’s always been (which is why it was always obviously a bad idea and should not have been included in the standard).
- codeflo 4y agoNo problem, just introduce intreallymax_t and later intmaxthistimewereallymeanit_t.
- formerly_proven 4y agoint -> intpro_t -> intmax_t -> intultra_t
- 4y ago
- avar 4y agoNot new in C23, but I still think it's a glaring hole in the standard that there's still no standard way to ask the compiler which (if any) of "J.5 Common extensions" is supported. For the C version you have __STDC_VERSION__, but there's no similar facility to check if e.g. J.5.7 is supported, which effectively makes the behavior that's explicitly omitted in 7.22.1.4 and 6.3.2.3 go from "undefined" to supported by C23 + the extension. I understand why C can't have some generic "is this undefined?" test, but it seems weird not to be able to ask if extensions defined in the standard itself are in effect, as they define certain otherwise undefined behavior. The effect is that anyone using these extensions must be intimately familiar with all the compilers they're targeting.
- ufo 4y agoWhy is stdbool.h deemed "mostly useless now"? Is it always available via another header now?
- pdw 4y agoIn C23, `bool`, `true` and `false` are available without including `stdbool.h`.
- ufo 4y agoGreat news! \o/
- cesarb 4y agoIt's great news unless you're maintaining software which defines its own version of these three keywords (which was necessary before C99, and AFAIK there is a popular C compiler which still doesn't have full support for C99). And until everyone moves to C23 (which will probably take a very long time; a quick web search tells me that it took until 2015 for the aforementioned popular C compiler to add support for the C99 stdbool.h header), all C projects will still have to include that header.
- pjmlp 4y agoIf 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.
- sigsev_251 4y agoI've heard that they are working on C11 atomics, now that the C++ standard includes <stdatomic.h> for compatibility with C.
- pjmlp 4y agoMight be, that was the main goal when they gave up on C, just to improve C compatibility to the extent of ISO C++ requirements. It was the whole change of management that somehow made them backtrack on that decision.
- zxwrt 4y agoSad that C23 didn't get symbol visibility attributes. They are very useful for libraries. Perhaps there is still a chance to get them?
- rwmj 4y agoI suppose because they are an ELF feature rather than a language feature? Anyway you can (and should!) use -fvisibility=hidden and add __attribute__((__visibility__("default"))) to public symbols when writing a C library. It will make calls between non-visible symbols faster because the compiler doesn't have to generate code to handle ELF symbol interposition.
- zxwrt 4y agoThese are non-standard GNU extensions, unfortunately.
- account42 4y agoAll compiler flags are non-standard because the C standard does not concern itself with them at all. That said, there are effectively two standard compiler interfaces: MSVC and GCC and everyone else emulates one or both of these. Similarily, symbol visibility is not something that the C standard cares about because it doesn't even care about libraries in the first place. Again, for all platforms that have symbol visibility (e.g. PE and ELF based ones, although the details differ) there is a defacto standard for the compiler flags and attributes to control the visilibity: the MSVC and GCC extensions.
- zxwrt 4y agoActually, the only compiler interface that can claim to call itself a standard is POSIX c99. Everything else is too volatile to be a standard.
- account42 4y agoYou might also want to compile with -fno-semantic-interposition since no one actually needs semantic interposition for symbols used and defined in the same library so you might es well disable it even or public functions.
- vbtemp 4y agoI have a question I've always wanted to know but too embarrassed to ask (Especially because I've extensively used C for well over a decade now and am intimately familiar with it): Who exactly are these new C-standards for? I interact and use C on an almost daily basis. But almost always ANSI C (and sometimes C99). This is because every platform, architecture, etc has at least an ANSI C compiler in common so it serves as the least common-denominator to make platform-independent code. As such it also serves as a good target for DSLs as a sort of portable-assembly. But when you don't need that, what's the motivation to use C then? If your team is up-to-date enough to quickly adopt C23, then why not just use Rust or (heaven forbid, C++23)? I'd love to hear from someone who does actively use "modern" C. I would love to be a "modern C" developer - I just don't and can't see its purpose.
- layer8 4y agoExisting C code needs to be maintained, and can take advantage of the newer features when available in the compiler. The Linux kernel is moving to C11, and may move to C17/C23 later. Also not everyone wants to put up with the compilation times, object sizes, and aesthetics of Rust. As for new developments, see for example https://news.ycombinator.com/item?id=33675462 https://news.ycombinator.com/item?id=33675462 which uses C11.
- fweimer 4y agoI doubt that the kernel will adopt the C++ memory model (the big change in C11). Instead, they will keep doing their own thing. Given the problems with the memory model, I can't really fault them. But framing this in terms of standards versions is a bit of a stretch. They could easily adopt additional GCC extensions over time as they move minimum compiler versions forward. Standardization does not really matter there.
- electroly 4y agoAre you asking about greenfield development only? One big obvious reason to use C23 instead of Rust or C++23 is if you already have a codebase written in C. Switching to C23 is a compiler flag; switching to Rust is a complete rewrite.
- phkahler 4y ago>> 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.
- layer8 4y agoIt might remove too many compiler optimization opportunities (see e.g. http://kristerw.blogspot.com/2016/02/how-undefined-signed-overflow-enables.html http://kristerw.blogspot.com/2016/02/how-undefined-signed-ov...) for the standard to disallow them now.
- ElevenLathe 4y agoMeaning there are too many compilers currently producing fast-but-probably-not-what-the-programmer-meant code that will need to be changed produce slower-but-probably-what-the-programmer-meant code? Or do I misunderstand? Seems like a win to me if so.
- pwdisswordfish9 4y agoSlower-and-probably-not-what-the-programmer-meant-either code.
- kllrnohj 4y agoNo, you misunderstand. Wide contacts are not universally superior to narrow ones, and more often than not narrow contacts catch more bugs than wide ones do. For example almost never does a programmer want int to rollover in a for loop. Defining that behavior doesn't help, and indeed makes tools like linters or sanitizers less useful.
- dzaima 4y agoIf you do "for (int i = 0; i < len; i++) data[i] = 0;" and len happens to be above 2^31, is your intent to write 2 billion zeroes, and then write 2 billion zeroes behind the data pointer, and repeatedly do that forever (never mind other UB that that results in)? Probably not. 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).
- mananaysiempre 4y agoTypo (I hope... :) ): BITITNT_MAX instead of BITINT_MAX, multiple times.
- sigsev_251 4y agoIf I remember correctly, it's not even correct. The macro is supposed to be named BITINT_MAXWIDTH.