Earlier quoted context omitted.
> Usually...probably... you're betting against the compiler ever improving.
This would be a regression
Everything in C is undefined behavior
621–630 of 748 posts
Re: Everything in C is undefined behavior
#622Earlier quoted context omitted.
I interpreted these words: > If you want to be standards correct, yes you have to know the standard well. to mean that being standards-correct is optional. It's not. Every C programmer needs to know every possible UB by heart and never introduce any of it to their code, or else they'll be constantly introducing subtle, hard to debug bugs that contradict the actual code they wrote. Maybe you meant something different…
Of course it's optional (although I didn't mean to imply that). Even using computers at all is optional. I never said that I don't aim to follow the standard, have a clean compiling program without warnings and without UB, etc. I do strive to achieve all of that. But it's not entirely black and white, either. In practice I'm fine accepting that some bugs are technically UB but whatever, we've found a bug by whatever…
To paraphrase your earlier comment - you lose low-friction polymorphism (unpredictable compiler output causes a lot of friction). You lose control of memory allocations (because they may have been elided) and lose control of lifetimes (because free can be moved before last use causing a crash, or removed entirely causing a leak). You lose control of (almost) anything that happens in the system. And it has everything to do with not following the standard.
You do retain control of the memory layout of data structures, though.
Re: Everything in C is undefined behavior
#623Earlier quoted context omitted.
Maybe I'm misunderstanding. Here is what I'm trying to say. "Accessing an object which is not correctly aligned" - this is UB "As an example of this, take this code: ..." - this (code) is not UB. Is this incorrect somehow? You could interpret the second sentence as 'under the assumption of an unaligned pointer, let's look at what this seemingly innocuous (and correct) code does.' But that's not what they did. They pr…
Edit: I think one part of the confusion is we were addressing different parts of the first example of the article. You were referencing the int foo(..) snippet (which I agree has no UB), but I was referencing the parse_packet() snippet (which has UB by construction), which was also part of the first example :). You are beginning to understand. Yes, surprisingly, it is (1) that is being claimed. The mere expression is…
But even for the parse() example, the issue is the aliasing rules (and not the alignment - though that could still be an issue depending on input!) Aliasing isn't even mentioned in the article. Instead the example presents this thing 'people do all the time' and identifies it 'UB' without even identifying the actual issue.
On its own I could forgive the former, making a precise example is tricky (particularly with alignment issues). But this is repeated: milliseconds() is characterized 'UB' because it's inputs could be outside the representable range. Again the function is not UB, the inputs can potentially trigger UB.
Then the function pointer example obfuscates the assignment (fine) with the call (ub). Despite the red herring statement 'NULL compares unequal to any object or function' as the example assigns a function _pointer_ which can be NULL. The honest example of the statement is:
void foo() = NULL;
which won't even compile because it violates the thing that was just said (among other reasons). The UB is the call below and has nothing to do with equality with NULL.The repeated pattern of say one thing, show an example that's 'reasonable' and implies that it's related to what was just said, and from that invalid relation conclude that everything is UB in C feels dishonest (particularly when it's so easy to talk about UB in C honestly because there is so much to be legitimately concerned about!)
I appreciate your and your advocacy about UB in C, and I think I agree with most of your points about it and they worth discussing. That's why the article itself is frustrating to me, we don't need to be tricksy when talking about UB, it's already tricky enough!
Re: Everything in C is undefined behavior
#624Earlier quoted context omitted.
> A check is only useful if you want to actually change the behavior when it happens, otherwise it is useless. You almost always want to change the behavior to erroring out on overflow. The few cases where overflow really is intended and fine can be handled by explicit opt-out. And I refuse to buy the argument that "small things add up" in the world where we do string building and parsing every few microseconds. Chec…
This string manipulation stuff is very common, and that's why in 2026, an age where science fiction has become a reality, many things are still absurdly slow. Exactly because of such sloppiness, which does accumulate in many cases, and when one least expected it.
Re: Everything in C is undefined behavior
#625Earlier quoted context omitted.
> because Assembly doesn't have UB To be pedantic, old hardware like 6502 family chips (Commodore 64, Apple II, etc) had illegal instructions which were often used by programmers, but it was completely up to the chip to do whatever it wanted with those like with UB.
> illegal instructions... were often used by programmers Intentionally, with an expected effect? I'd need a citation for that.
The benefits of being able to do stuff like this when you need to conserve resources are obvious, and common idioms have formed around their use. Check out https://csdb.dk/release/?id=198357
Re: Everything in C is undefined behavior
#626- Making a Turing machine have deterministic and predictable results is hard.
- Modern hardware is complex and getting all hardware to behave the same way requires a strong mathematical abstraction.
C was never intended to be a fully defined mathematical abstraction. It was a language which was easy to write a compiler for. That's its original strength. Trying to make it something it isn't is the problem. Either choose a language which does have such abstractions or understand the drawbacks of the tool you are using.
Right tool for the right job.
Re: Everything in C is undefined behavior
#627Can anyone explain why this is undefined behaviour? UBSan calls it "indirect call of a function through a function pointer of the wrong type" struct foo {int i;}; int func(struct foo *x) {return x->i;} int main() { int (*funcptr)(void*) = (int (*)(void*)) &func; struct foo foo = { 42 }; return funcptr(&foo); } While this is all kosher per the language lawyers: struct foo {int i;}; int func(void *x) {return ((struct f…
C23 §6.5.2.2p7 > If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined. Compatible types requires integrating texts from several different paragraphs, but the general notion is "identical type, in a frontend sense", not "same ABI." This means that "const void " and "void " are not compati…
I can see the value in saying that struct x* isn't compatible with struct y*, because they could have different alignment or packing rules. But struct x* and void*, which is already special-cased to allow assignment without a cast? Why aren't these considered compatible in function pointer parameter definitions?
Is there any work involved in casting void* to struct* (on any architecture) that a plain function pointer would miss out?
Re: Everything in C is undefined behavior
#628Earlier quoted context omitted.
Author here. > It barely scratches the surface. I agree. The point of the post is not to enumerate and explain the implications of all 283 uses of the word "undefined" in the standard. Nor enumerate all the things that are undefined by omission. The point of the post is to say it's not possible to avoid them. Or at least, no human since the invention of C in 1972 has. And if it's not succeeded for 54 years, "try hard…
> Now, is it exploitable that `find` also reads the uninitialized auto variable `status` (UB) from a `waitpid(&status)` before checking if `waitpid()` returned error? (not reported) I can't imagine an architecture or compiler where it would be, no. I presume you're referring to this code: pid = waitpid(pid, &status, 0); if (WIFEXITED(status)) rval = WEXITSTATUS(status); else rval = -1; The only signal handler find in…
But in my code, I would have fixed for the reasons you mention. Sprinkle enough of these around, and some low percentage will in the future have its assumption invalidated.
Re: Everything in C is undefined behavior
#629Earlier quoted context omitted.
I told someone at a conference that UB actually means "implementation-defined, no documentation required". He started to refute me and then stopped.
That isn't true, for UB the compiler is allowed to assume the UB can never happen. For example if you dereference a pointer and only after check if it is NULL, the compiler can remove the NULL check, since it is clearly impossible (nevermind that you might be on a microcontroller where NULL is a valid address). The fallout of this are quite large! If behaviour is implementation defined the compiler has to stick to on…
That is, the compiler de facto defines what happens when you compile UB code.
So you're not wrong, but I think you missed the sarcastic spin of parent.
Re: Everything in C is undefined behavior
#630Earlier quoted context omitted.
If it is defined as an error, but the compiled build will continue to run with the value wrapped around, I would say that's indistinguishable from UB.
No. An integer getting deterministically set to an unintended value is a bug. A bug is not the same thing as UB. (Even if it were non-deterministic, it would still not be anything like UB.) It's not the same ballpark, not even the same sport.