Live data from Hacker News

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

queue.acm.org

211–220 of 275 posts

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

#211

#embed is what I really want. And separators. > Standard C advances slowly They're not joking, either. C is conservative to a fault, I think.

> #embed is what I really want. And separators.

If you want to try out those features now, I made a pre-processor that translates that into standard C99:

https://sentido-labs.com/en/library/cedro/202106171400/use-e...

https://sentido-labs.com/en/library/cedro/202106171400/#numb...

It includes a cc wrapper called cedrocc that you can use as a drop-in replacement:

https://sentido-labs.com/en/library/cedro/202106171400/#cedr...

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

#212

Earlier quoted context omitted.

You're correct in practical terms, but I'm making a very pedantic point about what the standard requires happen, mainly because this pedantry has important implications for e.g. safety critical C. Note 1 to the definition in 3.4.3 provides some clarification about the extent of UB and states that UB can manifest at translation time. It also gives says that the translator should behave in a documented manner when enco…

C has both translation-time UB and runtime UB. (C++ explicitly separates the two concepts into "ill-defined, no diagnostic required" and "undefined behavior".) You can tell them apart from the condition for UB to occur: if it's a translation-time condition, then it's translation-time UB, and if it's a runtime condition, then it's runtime UB. (Same with implicit UB: is it a translation-time or a runtime assumption bei…

5.1.2.3 only binds conforming programs. Programs containing UB are by definition non-conforming.

I hadn't considered the C++ standard here, but 1.9 is much more clear than corresponding C verbiage. 1.9.5 is exactly what's described upthread, where any "execution [that] contains an undefined operation" has no prescribed behavior. But the note to the requirement immediately before that (1.9.4) doesn't use that language and instead "imposes no requirements on programs that contain UB". If they had intended only to avoid specifying semantics for programs that hit UB during some possible execution, they would have used the same language as 1.9.5.

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

#213
post #33

Earlier quoted context omitted.

the thing that makes UB almost malicious is that it propagates inter-procedurally. This makes reasoning about code with UB basically impossible which means that you should always assume that the compiler is going to screw you over if you use it because there is no way to know whether it will.

You should consider a program with undefined behaviour to be the equivalent of a mathematical proof that contains an unstated contradiction. Ex falso quodlibet : from a falsehood anything follows. Also called the principle of explosion. Undefined behaviour renders your entire program meaningless. It must be avoided at all costs. Using undefined behaviour on purpose is like sticking a fork in an electrical socket.

It's funny that your original post was an objection to how undefined behavior gives license to screw developers over, but here you are talking about how undefined behavior is like sticking a fork in an electrical socket.

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

#214

Earlier quoted context omitted.

Is the improved performance of C over say Java, or Rust (which both have much less undefined behaviour -- Java almost none) worth the pain and bugs which have been caused by UB? Honestly, I don't think so, and as computers get more powerful and the amount of the world which relies on their correct functioning grows, I feel the arguments for UB become increasingly difficult to justify.

I went to look up undefined behaviour in Rust and I got this scary warning: Warning: The following list is not exhaustive. There is no formal model of Rust's semantics for what is and is not allowed in unsafe code, so there may be more behavior considered unsafe. The following list is just what we know for sure is undefined behavior. Please read the Rustonomicon before writing unsafe code. After the warning was a lis…

C does not have a formal specification either. It has a standard's document that is written using formal English, but it does not provide a formal spec of C's semantics. A formal spec of a programming language's semantics would entail using a formal semantic model such as operational or denotational semantics. Some programming languages do specify the formal semantics for the entire language or some subset of the language but C is not one of them.

Your claim that the C Standard lists all undefined behavior is actually false. The C Standard only lists out the explicit list of undefined behavior, but it does not list out the implicit list of undefined behavior. There have been efforts to make just such a list but it's an incredibly difficult task.

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

#215
post #185

Earlier quoted context omitted.

> you’d have to insert a check every time you add two signed integers together, This is exactly what is done in serious code. It is typically combined with contracts and static analysis (often human), e.g. "it is guaranteed that this input is in range 10-20, so adding it with this other 16 bit int can be assumed to be below sint32_max".

Great, those checks can stay in "serious" code, and those of us who don't want them can take the UB. C++ 20 actually ended up specifying that all ints are twos complement, removing this from the category of "UB," but a lot more weird stuff is programmed in C.

Note that signed overflow is still UB in c++ even with 2-complement being guaranteed for signed types.

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

#216

Earlier quoted context omitted.

You're correct in practical terms, but I'm making a very pedantic point about what the standard requires happen, mainly because this pedantry has important implications for e.g. safety critical C. Note 1 to the definition in 3.4.3 provides some clarification about the extent of UB and states that UB can manifest at translation time. It also gives says that the translator should behave in a documented manner when enco…

Fine. HN is, after all, a place where you can be pedantic. But those of us who are actually writing programs mostly care about "in practical terms", and in practical terms, this doesn't happen, so we don't care . We've got enough trouble worrying about what does happen; we don't have time and energy to worry about what doesn't and won't happen.

To provide some more context/motivation for why you might care, I write safety-critical code. I'm often advising people what they need to do for certification, etc. If all you need to do is ensure that you never execute undefined operations and knock out the list of specified UB, that's totally, 100% manageable. Throw some sanitizers on, provide realistic input, and test the hell out of it. Normal stuff.

If the reality is that any UB can invalidate the entire program (as is the interpretation taken by other standards re: C), then that's not remotely sufficient. You have to ensure the complete absence of UB.

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

#217

Earlier quoted context omitted.

C has both translation-time UB and runtime UB. (C++ explicitly separates the two concepts into "ill-defined, no diagnostic required" and "undefined behavior".) You can tell them apart from the condition for UB to occur: if it's a translation-time condition, then it's translation-time UB, and if it's a runtime condition, then it's runtime UB. (Same with implicit UB: is it a translation-time or a runtime assumption bei…

5.1.2.3 only binds conforming programs. Programs containing UB are by definition non-conforming. I hadn't considered the C++ standard here, but 1.9 is much more clear than corresponding C verbiage. 1.9.5 is exactly what's described upthread, where any "execution [that] contains an undefined operation" has no prescribed behavior. But the note to the requirement immediately before that (1.9.4) doesn't use that language…

[deleted]

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

#218

Earlier quoted context omitted.

C has both translation-time UB and runtime UB. (C++ explicitly separates the two concepts into "ill-defined, no diagnostic required" and "undefined behavior".) You can tell them apart from the condition for UB to occur: if it's a translation-time condition, then it's translation-time UB, and if it's a runtime condition, then it's runtime UB. (Same with implicit UB: is it a translation-time or a runtime assumption bei…

5.1.2.3 only binds conforming programs. Programs containing UB are by definition non-conforming. I hadn't considered the C++ standard here, but 1.9 is much more clear than corresponding C verbiage. 1.9.5 is exactly what's described upthread, where any "execution [that] contains an undefined operation" has no prescribed behavior. But the note to the requirement immediately before that (1.9.4) doesn't use that language…

Your claim is actually false. C differentiates between a conforming program and a strictly conforming program. 5.1.2.3 binds to conforming programs which is permitted to produce output dependent on undefined behavior.

Only strictly conforming programs may not produce output dependent on undefined behavior.

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

#219

Earlier quoted context omitted.

That's not an argument to keep live grenades laying around, it's an argument to remove them from the spec. Like signed int being UB. Define it to have 2 complement semantics. Problem solved. I'm sure the nutters trying to extend C++ with templates will howl but this is C not C++. And seriously C++ is dead man walking at this point.

C23 does make two’s complement standard. It also adds checked arithmetic so you can safely avoid signed overflow. It does not make signed overflow defined behaviour. This would prevent integer operation reordering as an optimization, leading to slower code.

Yeah but it's reversed signed overflow shouldn't be UB by default. You should have to explicitly opt in for that.

The reason of course why they refuse to do that if because if that were that case most shops would up and ban unsafe signed.

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

#220
post #178

Earlier quoted context omitted.

That's not the correct syntax for the ckd_ operations. They take 3 operands, the first being a pointer to an integer where the result should be stored. And they return a bool, which you need to check in a conditional. If you're just going to throw out the bool and ignore the overflows, why bother with checked operations in the first place?

Yeah, I realize that now. That's even worse. So you'll have to write something like int aa,twoa,twoab,bb,aaplustwoab,aaplustwoabplusbb; if (ckd_mul(a,a,&aa)) { return error; } if (ckd_mul(2,a,&twoa)) { return error; } // … if (ckd_add(aaplustwoab,bb,aaplustwoabplusbb)) { return error; } return aaplustwoabplusbb; So ergonomic! > If you're just going to throw out the bool and ignore the overflows, why bother with check…

Why not just write:

    bool aplusb_sqr(int* c, int a, int b) {
        return c && ckd_add(c, a, b) && ckd_mul(c, *c, *c);
    }
Post reply on HN