TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Catch-23: The New C Standard Sets the World on Fire

245 pointsby donmccabout 2 years ago

26 comments

Dylan16807about 2 years ago
&gt; C23 furthermore gives the compiler license to use an unreachable annotation on one code path to justify removing, without notice or warning, an entirely different code path that is not marked unreachable: see the discussion of puts() in Example 1 on page 316 of N3054.9<p>I don&#x27;t agree with that description at all. Here&#x27;s the code:<p><pre><code> 1 if (argc &lt;= 2) 2 unreachable(); 3 else 4 return printf(&quot;%s: we see %s&quot;, argv[0], argv[1]); 5 return puts(&quot;this should never be reached&quot;); </code></pre> The only code path that&#x27;s &quot;entirely different&quot; is lines 1,4,5 and in that case of course you remove a return that&#x27;s after a return.<p>And the other valid code path is 1,2,5, which has `puts` after `unreachable`.<p>To need `puts` you have to imagine a code path that gets past the &quot;if&quot; without taking either branch?<p>Maybe the author means something by &quot;code path&quot; that&#x27;s very different from how I interpret it?<p>I would be pretty surprised if the above code means something different from:<p><pre><code> if (argc &lt;= 2) { unreachable(); return puts(&quot;this should never be reached&quot;); } else { return printf(&quot;%s: we see %s&quot;, argv[0], argv[1]); return puts(&quot;this should never be reached&quot;); }</code></pre>
评论 #35407070 未加载
评论 #35406395 未加载
评论 #35412582 未加载
评论 #35409066 未加载
评论 #35407381 未加载
评论 #35407511 未加载
评论 #35408862 未加载
i-use-nixos-btwabout 2 years ago
This is written with quite a lot of hyperbole.<p>The predominant focus is realloc(pre,0) becoming UB instead of what the author misleadingly describes as useful, consistent behaviour. It is far from that, and that’s the entire reason that it was declared UB in the first place: <a href="https:&#x2F;&#x2F;www.open-std.org&#x2F;jtc1&#x2F;sc22&#x2F;wg14&#x2F;www&#x2F;docs&#x2F;n2464.pdf" rel="nofollow">https:&#x2F;&#x2F;www.open-std.org&#x2F;jtc1&#x2F;sc22&#x2F;wg14&#x2F;www&#x2F;docs&#x2F;n2464.pdf</a>. Note that this wasn’t a proposal to change something, it’s a defect report: the original wording was never suitable.<p>The second part is the misconception about the impact of UB. Making something UB does not dictate that its usage will initiate the rise of zombie velociraptors. It grants the implementation the power to decide the best course of action. That is, after all, what they’ve been doing all this time anyway.<p>Note that this deviates from implementation-defined behaviour, because an implementation-defined behaviour has to be consistent. Where implementations choose to let realloc(ptr,0) summon the zombie raptors, they are free to do so. Don’t like it? Don’t target their implementation. Again, this isn’t a change from the POV of implementers - it’s a defect in the existing wording.<p>In this case, the course of action that any implementation will choose is to stick with the status quo. It is clearly not a deciding factor in whether or not you embrace the new standard, and to suggest otherwise is dishonest, sensationalist nonsense. The feature was broken, and it’s just being named as such.
评论 #35405650 未加载
评论 #35405674 未加载
评论 #35406820 未加载
评论 #35409181 未加载
评论 #35412051 未加载
评论 #35408511 未加载
评论 #35408329 未加载
GuB-42about 2 years ago
I actually like unreachable() a lot. What it does is that it invokes undefined behavior, that&#x27;s all.<p>It does nothing trickier than any other kind of UB. In fact, I could implement unreachable() like this: void unreachable() { (char *)0 = 1; }.<p>Standardizing it however gives interesting options for compilers and tool writers. The best use I can find is to bound the values of the argument of a function. For example, if we have &quot;void foo(int a) { if (a &lt;= 0) unreachable(); }, it tells the compiler that a will always be &gt;0 and it will optimize accordingly, but it can also be used in debug builds to trigger a crash, and static analyzers can use that to issue warnings if, for example, we call foo(0). The advantage of using unreachable() instead of any other UB is that the intention is clear.
评论 #35408703 未加载
评论 #35415604 未加载
评论 #35415930 未加载
firstlinkabout 2 years ago
&gt; and that such changes may impose themselves on old code without recompilation when dynamically linked libraries are upgraded.<p>All I can do is laugh. This is what the dynamic linker fanatics wanted. This is what they explicitly advocate for to this day. Share and enjoy!!
评论 #35405871 未加载
评论 #35406370 未加载
评论 #35407304 未加载
评论 #35405840 未加载
GuB-42about 2 years ago
&gt; C178 purports to be a bug-fix revision of C11. Does the word &quot;toto&quot; on page 1 indicate (a) the editor&#x27;s musical tastes; (b) that nobody bothered to spell-check the document; (c) that we&#x27;re not in Kansas anymore; or (d) none of the above?<p>As a french guy I&#x27;d go with (d).<p>I&#x27;ve often seen &quot;toto&quot; used as a placeholder name, sometimes followed by &quot;titi&quot;, &quot;tata&quot;, &quot;tutu&quot;, I have even used it myself. It is similar to &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;. I don&#x27;t know if it is specific to France, of French speaking countries, but it is definitely a thing here.
评论 #35408726 未加载
RustyRussellabout 2 years ago
Frankly, the C standards ctte went off the deep end when they effectively banned NULL to memset etc (obv with zero length).<p>Not because these functions couldn&#x27;t handle it, but because this assertion simplifies optimizations <i>elsewhere</i>.<p>This has required adding extra checks in my code, found mainly by trial and error, and has made it less readable <i>and</i> less optimal.<p>Finally, the checked arithmetic operations returning <i>false</i> on success is a horror show. Fortunately it will be found on the first time the code is run, but that&#x27;s a damnably low bar :(
评论 #35405770 未加载
评论 #35410229 未加载
评论 #35407437 未加载
评论 #35407024 未加载
JonChesterfieldabout 2 years ago
Author is angry but not wrong. Lifting the most damning quote from the article as I haven&#x27;t seen it for a while.<p>C inventor Dennis Ritchie pointed to several flaws in [ANSI C] ... which he said is a licence for the compiler to undertake agressive opimisations that are completely legal by the committee&#x27;s rules, but make hash of apparently safe programs; the confused attempt to improve optimisation ... spoils the language.<p>—Dennis Ritchie on the first C standard
juunppabout 2 years ago
&gt; The ckd_* macros steer a refreshingly sane path around arithmetic pitfalls including C&#x27;s &quot;usual arithmetic conversions.&quot;<p>A 7 letter function to add two numbers and that returns a boolean... not entirely sure I&#x27;d call that &#x27;sane&#x27;.
评论 #35407062 未加载
ChancyChanceabout 2 years ago
Is the world finally realizing that &quot;a + b&quot; actually returns two values: pass&#x2F;fail and the value if pass?<p>&quot;a + b = c;&quot; is a fundamentally flawed operation from a computer architecture perspective.
评论 #35405800 未加载
评论 #35405714 未加载
评论 #35406980 未加载
评论 #35406807 未加载
solidsnack9000about 2 years ago
&quot;Looking forward, marijuana legalization will surely beget notions such as fractional-, imaginary-, and negative-length objects, each with as much potential for mayhem as zero-length objects.&quot;<p>It&#x27;s a funny thing to say.
评论 #35405810 未加载
评论 #35406309 未加载
GianFabienabout 2 years ago
Maybe I&#x27;m being dense. To me it appears that the standards are telling compiler writers what should be done. In doing so the compilers will become ever more complex and thus bug-prone.<p>I learnt C back when K&amp;R (first edition) was the reference. Ok, it was hardly much more than a universal assembler to make every computer look like a PDP-11. In my experience C is the language to use when you want to be close to the metal. For the rest I use which ever high-level language&#x2F;environment is best suited. Admittedly some FFI are a pain to use, but once you get the boilerplate bedded down your much higher level language gets the coordination done.
评论 #35406053 未加载
antiquarkabout 2 years ago
C reached its zenith in C90, and saw a few good ideas in C99. Everything since has been wankery from people who either are bored, or have a severe case of C++-envy.
评论 #35408872 未加载
andrepdabout 2 years ago
&gt; All C standards from C89 onward have permitted compilers to delete code paths containing undefined operations—which compilers merrily do, much to the surprise and outrage of coders.16 C23 introduces a new mechanism for astonishing elision: By marking a code path with the new unreachable annotation,12 the programmer assures the compiler that control will never reach it and thereby explicitly invites the compiler to elide the marked path.<p>I don&#x27;t agree with this in the slightest. I&#x27;m not &quot;outraged&quot; by undefined behaviour, it&#x27;s a <i>fundamental tool</i> for writing performant code. Ensuring that dereferencing a null pointer or accessing outside the bounds of an array is undefined behaviour is what lets the compiler not emit a branch on every array access and pointer dereference.<p>Furthermore, I really don&#x27;t understand the outrage that there is another <i>explicit</i> tool to achieve behaviour the author may or may not consider harmful. If it&#x27;s an explicit macro, it&#x27;s not a tarpit!
layer8about 2 years ago
While the situation with realloc() is unfortunate, it is also not difficult to write a wrapper that does what the author wants. I’ve done that before, because it has long been known that not all realloc() implementations conform to the (prior) C standard. One can furthermore assume that existing implementations won’t change their behavior just because C23 made it UB.
评论 #35411898 未加载
a-bit-of-codeabout 2 years ago
Is it just me that thinks that the article is a [skilfully drafted] joke (or parody or whatever the correct word is)? The fact that it has been published close to April 1st raises more suspicions.
评论 #35408489 未加载
评论 #35414081 未加载
eternalbanabout 2 years ago
C is a very large language masquerading as a small language.
评论 #35408866 未加载
评论 #35406048 未加载
quintussssabout 2 years ago
I always wonder how much these new C standards use, as C is now mostly used in areas where one is severely limited when it comes to compiler choice. Where I work, we use GCC 6.2 and iso9899:1990 (C90). If we were able to use a modern compiler, we would probably just use C++.
tzsabout 2 years ago
&gt; Pointers to free&#x27;d memory are akin to uninitialized pointers, so free(p) followed by if (p==q) is an instrument of arson<p>What&#x27;s the reason for this?
评论 #35407041 未加载
评论 #35407217 未加载
评论 #35406387 未加载
评论 #35406498 未加载
__sabout 2 years ago
tl;dr `realloc(p, 0)` is slated to be undefined behavior in C23, whereas it&#x27;s been somewhat implementation defined until now, with recommendation being realloc(p, 0) is equivalent to free(p)<p>Seems a bit tone deaf to create new undefined behavior in memory handling, especially when a sane default behavior seems to be de facto<p>I&#x27;ve used that free-on-0 behavior myself. Unfortunately the code that uses this will often have 0 be a length variable, so hard to grep for this. Ideally musl&#x2F;glibc will both stick to that undefined behavior being free &amp; gcc&#x2F;clang won&#x27;t go about making this something to point their optimizations at<p>Lest we have to stop using realloc outside of a safe_realloc wrapper<p><pre><code> static void *safe_realloc(void *p, size_t newlen) { if (newlen == 0) { free(p); return NULL; } return realloc(p, newlen); } </code></pre> What got this whole thing weird is that C doesn&#x27;t like zero sized objects, but implementations were allowed to return a unique pointer for a zero sized allocation. Which then raises the matter that being portable there require freeing that reserved chunk for non-free implementations. In theory this reservation code could be more efficient when code frequently reallocates between 0 &amp; some small value. &amp; there was uncertainty because NULL is a way to say allocation failure, but then if one did a NULL check on realloc&#x27;s return value they also had to check that the size was non-zero
评论 #35405662 未加载
评论 #35406199 未加载
评论 #35405948 未加载
blippageabout 2 years ago
#embed is what I really want. And separators.<p>&gt; Standard C advances slowly<p>They&#x27;re not joking, either. C is conservative to a fault, I think.
评论 #35412721 未加载
pjmlpabout 2 years ago
And zero focus on improving the root causes of memory corruption due to strings and array indexing errors.<p>The security world will keep burning it seems.
评论 #35409472 未加载
otabdeveloper4about 2 years ago
Hopefully not literally. (But C23 is exactly the kind of programming language you expect to do that.)
Dweditabout 2 years ago
Did we ever legalize type punning?
评论 #35408156 未加载
评论 #35407590 未加载
评论 #35409034 未加载
cryptonectorabout 2 years ago
The `realloc()` change calls for pitchforks.
kgbciaabout 2 years ago
I just need built-in string handling
评论 #35417225 未加载
MatmaRexabout 2 years ago
&gt; As C89 was taking shape, the neurodivergent notion of a &quot;zero-length object&quot; was making the rounds<p>I&#x27;m surprised that the authors decided to, and were able to, slip in this little euphemism.
评论 #35406566 未加载
评论 #35406928 未加载
评论 #35407179 未加载
评论 #35407816 未加载