Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

401–410 of 503 posts

Re: Undefined behavior in C is a reading error

#401
post #278

Earlier quoted context omitted.

UB, in this context, is very explicitly used in the standard: it is undefined behavior related to a construct that the standard describes.

> behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements That is literally the definition of UB from the C standard. It is explicitly also about constructs that the standard does not describe. That makes sense: the standard does not and cannot define the behaviour for any construct not in the standard, so cannot impose any…

The relevant discussion about UB is restricted to constructa that the standard describes. For example, writing past the end of object is UB - the construct is described in the standard, but is given no semantics by the standard.

The standard does not describe pattern matching, so using pattern matching is also undefined behavior, but there is nothing to be talked about here.

Re: Undefined behavior in C is a reading error

#402
post #163

Earlier quoted context omitted.

What do you mean by "these UB optimizations"? C is a low-level language; it's basically impossible for a compiler to reason about the code unless it makes certain assumptions. It needs to assume the code is not self-modifying to do pretty much any code-generation more intelligent than a macro assembler. It needs to assume the code isn't messing with the stack frames/return addresses in order to inline functions. It n…

> most compilers provide a choice (-fwrapv, -fno-strict-aliasing, ...). Yet few projects use these options, Even if you opt into those (and the projects I've been involved with have), the precedent is established: when new compiler optimizations are introduced with disruptive semantics, they are opt-out, not opt-in — a fail-dangerous failure mode. > Doesn't that indicate that C programmers indeed want to sacrifice sa…

> Even if you opt into those (and the projects I've been involved with have), the precedent is established: when new compiler optimizations are introduced with disruptive semantics, they are opt-out, not opt-in — a fail-dangerous failure mode.

Actually, the default for gcc is -O0. You are opting in with -O2 etc.

Re: Undefined behavior in C is a reading error

#403

Earlier quoted context omitted.

Yes, some UB are not decidable at compile time, but a lot could be easily speced to have a defined behavior at runtime, such as overflows. The main reason to not spec these things is because people would be arguing "this makes compiled code on my esoteric 9-bit 1-complement chip slower" or "there was this chip in the 70s that did things differently" or "but a short int on Cray was 64-bit". Great, so now the spec has…

Note that (void *)0 is always NULL, as mandated by the standard. But, to address the content of your comment: defined behavior at runtime is not necessarily good behavior at runtime. Defining signed integer overflow to wrap, for example, is probably a bad idea, because this is rarely the intent of the code. Having all such operations trap might be a good idea, but now you're going to get the same "stop breaking my wo…

> Note that (void *)0 is always NULL, as mandated by the standard.

Also note that this is distinct from the memory representation of (void *)0 being all 0 bits, which is explicitly not mandated.

Re: Undefined behavior in C is a reading error

#404
post #385

Earlier quoted context omitted.

The spirit of the article and your comment seems to underrate the efforts required to come up with something like the standard for a C compiler. It's not a "perverse shield". In C, "optimize for correctness" is the programmer's job. I don't want to sound dismissive, and I don't pretend you to write a compiler, but please tell me how would you word a global standard for generating compilers that can compile for hundre…

I am sympathetic with the view that compiler writers are trapped by the architectures they have to support. However, I think there's just a philosophical difference here about what compilers are for: are they responsible for emitting correct programs; or are they for literal transpiling? Regardless of the history which has led to the latter outcome for C, I have to agree with the author that I think K&R's original vi…

> emitting correct programs; or are they for literal transpiling?

I guess the former. I am sure you are familiar with the "garbage-in, garbage-out" concept. The rules are set in the standard. If you feed the compiler with code outside the rules of the standard (even if syntactically correct), you cannot expect correct programs 100% of the time. The standard (somehow) guarantees that code that follows the rules should translate into correct programs. Some of the rules dictate the compiler to "do this", other dictate "do something but specify what you are doing" and "do whatever you want, including exploding, I don't care". Many of these rules are this way for the sake of generating optimized code.

These are the rules.

Are these rules too many to remember? Unfortunately yes, they are.

> I just have to imagine there is something a little better than the present attitude.

My crazy hope is that someday runtime checks will be done at silicon level. That is, compiler emits instructions declaring "this is an array of this dimension", and every time this array is accessed with the proper instructions (and the CPU is somehow aware of this), it triggers an interrupt when accessed out of bounds, for example.

> Could there not be a --hault-on-all-undef with a serious attempt to realise that in as many respects as possible?

It might not be possible for every piece of code. It will have to stop the compilation (or execution with runtime checks) at every int increment/operation. So I think that if rules cannot be generally applicable then they shouldn't be applicable at all.

Re: Undefined behavior in C is a reading error

#405
post #383

Earlier quoted context omitted.

What I never see mentioned in this type of discussion is what this compiler trick buys us. Like how much faster does my program run because of deductions like these? And are there any patterns that particularly benefit from it? Could they hint the constraint manually?

There are plenty of examples in this thread alone. In my opinion hinting won't help. Everyone who cares about the performance gain will enable the hint (which I expect will be almost everyone) so you have won nothing but added noise with the hint.

There is not a single compelling example. Just contrived examples with dubious speedups and obvious errors.

Re: Undefined behavior in C is a reading error

#406

Earlier quoted context omitted.

Stack layouts are only really relevant at ABI boundaries. In these cases the layout is usually specified in extensions to C or in other ways, such as handwritten assembly.

Linux clone, pthreads, and os code commonly look at stack boundaries

Not sure what you are referring to with stack boundaries. Of course the ABI imposes some minimal requirements at ABI visible points, but these days you can't even rely on the existence of frame pointers to traverse the stack and you have to use the DWARF unwind machinery. And the content of the stack frame itself is completely unspecified of course.

Re: Undefined behavior in C is a reading error

#407
post #390

Earlier quoted context omitted.

No, but still not even that gets the love it deserve. And a famous commercial variant of it has been PC-lint from https://www.gimpel.com/ . Being available on open source compilers does little to change the culture, as per latest surveys only 11% of developers care to use any kind of tooling for improving their code quality in C and C++. At CppCon a couple of years ago, only about 1% of the audience answered positive…

Those numbers are indeed a bit depressing.

Here is a recent survey, with a more positive number of about 37%, see question 10.

https://isocpp.org/files/papers/CppDevSurvey-2021-04-summary...

Re: Undefined behavior in C is a reading error

#408

Earlier quoted context omitted.

How is the compiler supposed to know that a particular operation is intended as an overflow check though? It isn't a human and it doesn't actually comprehend the code it operates on. It just blindly applies rules. I want the compiler to eliminate redundant operations. That's a large part of the point of doing optimizations in my view! Best effort attempts to avoid eliminating obvious sanity checks are desired of cour…

You are advocating incorrect code that uses a few less machine operations than correct code.

The compiler should have valid rules, not invalid ones.

Re: Undefined behavior in C is a reading error

#409
post #278

Earlier quoted context omitted.

> behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements That is literally the definition of UB from the C standard. It is explicitly also about constructs that the standard does not describe. That makes sense: the standard does not and cannot define the behaviour for any construct not in the standard, so cannot impose any…

The relevant discussion about UB is restricted to constructa that the standard describes. For example, writing past the end of object is UB - the construct is described in the standard, but is given no semantics by the standard. The standard does not describe pattern matching, so using pattern matching is also undefined behavior, but there is nothing to be talked about here.

The comment I replied to did talk about something not described by the standard though, namely syscalls. If you want to argue that we should not be talking about syscalls here, your issue should be with the original comment that brought them up (https://news.ycombinator.com/item?id=27222325), not with my reply, I think. However, that comment looks perfectly fine to me. Also, depending on how the syscalls are made, it actually may be explicitly described as UB by the standard, see my comment https://news.ycombinator.com/item?id=27228701 too.

Re: Undefined behavior in C is a reading error

#410
post #232

Earlier quoted context omitted.

> For example, if signed integer overflow yielded an unspecified result rather than causing undefined behavior, I wonder if any implementations would be adversely affected. I suspect so - makes it harder to reason about loop counts because the compiler can't necessarily guarantee that an incremented loop counter won't become negative and thus the loop needs to iterate more. E.g. something like for (int i=param; i Tha…

That's the exact reason why this rule was introduced into the standard: it was so C compilers could compete with Fortran compilers (Fortran has similar rules and at the time they were beating C compilers on equivalent scientific codes by 2-3x). Fortran has even more restrictive aliasing rules than C: a function is allowed to assume that any two array arguments passed as arguments do not overlap. If they do, the behav…

Exactly - it was done for meaningless benchmarking reasons. C programmers would be happy to use "restrict" as an opt-in for those, but this argument about FORTRAN goes back to the initial days of the standard when Dennis Ritchie had to push "noalias" out of the proposed standard.
Post reply on HN