Path: csiph.com!weretis.net!feeder9.news.weretis.net!panix!.POSTED.spitfire.i.gajendra.net!not-for-mail From: cross@spitfire.i.gajendra.net (Dan Cross) Newsgroups: comp.lang.c Subject: Re: Safety of casting from 'long' to 'int' Date: Fri, 8 May 2026 19:06:11 -0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Message-ID: <10tlc73$qq2$1@reader1.panix.com> References: <10su8cn$am9i$1@dont-email.me> <10tdu47$pms4$3@kst.eternal-september.org> <10tgqgk$rpk$1@reader1.panix.com> <10thb36$1prnt$1@kst.eternal-september.org> Injection-Date: Fri, 8 May 2026 19:06:11 -0000 (UTC) Injection-Info: reader1.panix.com; posting-host="spitfire.i.gajendra.net:166.84.136.80"; logging-data="27458"; mail-complaints-to="abuse@panix.com" X-Newsreader: trn 4.0-test77 (Sep 1, 2010) Originator: cross@spitfire.i.gajendra.net (Dan Cross) Xref: csiph.com comp.lang.c:398524 In article <10thb36$1prnt$1@kst.eternal-september.org>, Keith Thompson wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes: >> [snip] >> The `realloc` thing was a particularly egregious example of a >> thing that started life well-defined, then became IB, and then >> UB; it's relevant because it shows the committee is willing to >> make weaken the language's guarantees about what is well-defined >> over time, but I admit that that is rare. >> >> Another example I saw a few years ago, pre-pandemic, was an >> instance of LLVM lowering storage of a volatile-qualified struct >> type that was, IIRC, 7 bytes long into two 32-bit stores. The >> problem was that these stores overlapped one another, with the >> effect that one byte was written twice. I am friends with >> some of the LLVM/clang devs, and at the time I sat in an office >> down the hall from them. We were talking about it after lunch >> one day, and all of us agreed that the behavior was wrong, but >> the LLVM folks pointed out that it was not illegal as far as the >> standard was concerned because the semantics of `volatile` were >> basically unspecified (the standard was/is very unclear on this) >> and non-portable, and thus a credible argument could be made >> that this fell fall under the definition of UB, so technically >> the compiler wasn't incorrect. >> >> At this point I got frustrated, threw up my hands, and said, >> "you guys can't keep holding up the standard as a talisman >> against common sense." (They thought that was funny and wrote >> it on the whiteboard in someone's office.) >> >> It wasn't even so much that they thought that was a correct >> argument, just that they thought someone would bring it up in >> defense of the current behavior. > >OK, but that doesn't sound like an example of something that became >UB in a later edition of the standard. The same issue would apply, >I think, anywhere from C90 to C23. It is not clear to me that `longjmp` out of a non-nested signal handler is still well-defined as of C11, though it is explicitly stated to be C89. Beyond that, I'm going to weasel a bit, and I do apologize in advance. Note that my original statement, in response to Scott's statement about a programmer's responsibility and UB, included software that predated the standard, or that were standardized in a subsequent revision. For example, threads and a memory model didn't arrive until C11, but people have been writing wrappers around atomic operations and using (for example) pthreads for quite a bit longer. Now, as I read it, I think all of that falls under the rubric of UB (non-portable almost by definition), so all bets are off. But a programmer who took care to write that program in, say, the POSIX environment, and ensure it followed best practices and conformed to all available standards to the best of their ability, may be understandably miffed if their code suddenly stops working. "Well, using pthreads is UB as far as C is concerned" is a bit of a cop-out as an explanation for that. But less weaselly, I think my earlier `mul` example from elsewhere in the thread is not a bad illustration of the _kind_ of thing I meant. Given this, `uint16_t mul(uint16_t a, uint16_t b) { return a * b; }` a programmer who wrote this may be surprised that it exhibits UB on a platform with 32-bit, where `uint16_t` is defined to be `unsigned short`, particularly if they wrote it on a 16-bit platform where `typedef unsigned int uint16_t;` was the definition. >(I presume the target was on on which misaligned 32-bit stores >work correctly.) It was: x86. - Dan C.