Live data from Hacker News

Falsehoods programmers believe about undefined behavior

predr.ag

151–160 of 233 posts

Re: Falsehoods programmers believe about undefined behavior

#151

Earlier quoted context omitted.

Nope, the C spec is just really bad. The NULL check is allowed to be removed.

So the pseudocode: if (p is not NULL) { dereference p } is UB? That's crazy, but not actually unbelievable.

I am not certain of the language lawyer side of it, but no reasonable (or even moderately unreasonable) compiler would omit that check because of the guarded behavior; way too much code would break, probably including that compiler's standard library.

Re: Falsehoods programmers believe about undefined behavior

#152
post #109

Earlier quoted context omitted.

I have almost no idea about C compilation but would it be possible with macros or somehow redefining int?

I don't think it'd be possible to get the compiler to treat unsigned integer overflow as defined using macros. But I'm not a subject matter expert.

Not cleanly, but if you assume 2s complement and wrap all signed addition in a macro function you could cast to unsigned before the add and cast the result back to signed.

Re: Falsehoods programmers believe about undefined behavior

#153

Earlier quoted context omitted.

Read the gcc mailing list. There is alot of user hostile "fix your broken program" from language lawyers. I think aliasing rules messes up memcpy if you are dogmatic?

I think memcpy is fine because it operates on a special type that is allowed to alias anything. Strict aliasing has other fun issues like the impossibility of implementing malloc-like functions or the lack of any requirement for access to non-char members of structs to work at all[0]. [0]: https://stackoverflow.com/questions/49298704/how-reason-abou...

memcpy is UB because it reads padding bytes in structs.

memmove fails as it requires pointer comparisons between separate allocations, which is UB.

Re: Falsehoods programmers believe about undefined behavior

#154
I have another falsehood: most programmers believe that people working with C/C++ are constantly battling against UB all day long, five days a week, and that they are irresponsable and careless. That they should live in fear and terror, because "unsafe" is around the corner, and that their programs are not mathematically proven and that they might containt an explotaible bug because, you know, every other C/C++ program opens a socket to the internet or is a "sudo" kind of tool.

Re: Falsehoods programmers believe about undefined behavior

#155

> Here's the list of guarantees compilers make about the outcomes of undefined behavior: > That's the whole list. No, I didn't forget any items. Yes, seriously. I’m a little disappointed there isn’t an empty or in the middle there. I imagine screen readers would announce something like “list, zero items”.

Post author here. I'm very curious about the screen reader idea. If you or someone else is able to confirm what a good screen reader might do currently / what it might do with an empty list element, I'll happily update the post to whatever is the better behavior. I wish there were a best practices doc + a matching linter for accessibility things like this.

I just tested "" in VoiceOver on Mac and nothing gets read. Different screen readers are notoriously inconsistent though.

> I wish there were a best practices doc + a matching linter for accessibility things like this.

This sounds like it was meant to be a fun tweak/joke for screen readers but it's accessible without.

So it's not practical to automate a lot of accessibility checks like this one because it depends on context and there's subjectivity to it, similar to visual design and text readability. The best way to get more of a feel for this is to try a popular screen reader for your OS, do the tutorial, and try it on the page yourself.

Re: Falsehoods programmers believe about undefined behavior

#156
post #62
post #47

Earlier quoted context omitted.

UB "making dead code live again" is not an example of UB in dead code making the execution undefined. Yes UB in live code can have surprising effects, including executing dead code.

Unless your code is actually commented out (actually dropped from the program), it can still (maybe) execute. I think the main reason for this is an if(testSomeState()) { //code with UB } block being optimized to just //code with UB. Functions which are unreachable, maybe I agree, they can't be executed (without UB somewhere in reachable code). I'm not sure that's true though - if you have UB in your hardware (not yo…

If UB happens¹, anything can happen. So if the check can only happen after UB, or leads to UB, it can be removed. That isn't the case in your example – testSomeState() can return false (and if it can't, it getting optimized out is unrelated do the code it guards). Points 14-16 from the article are just nonsense, UB is a runtime concept and dead code doesn't run unless you already triggered UB¹.

¹or is guaranteed to happen in the future

Re: Falsehoods programmers believe about undefined behavior

#157
post #44
post #6

The biggest problem with UB, as interpreted by C/C++ compilers is the unfounded belief that the spec says that you can assume any path that leads to UB is defacto incorrect and can be ignored. That's the bogus logic required for steps 13-16 to be true. That interpretation of the specification language is clearly bogus as that means more or less all C and C++ programs can be compiled to a single return instruction - w…

This is an absurd reduction of the current situation. > That interpretation of the specification language is clearly bogus as that means more or less all C and C++ programs can be compiled to a single return instruction - when compiler devs introduced this new new interpretation of UB, it turned out they had to then go through and add a bunch of exceptions for basics like memset, memcpy, and memmove could work withou…

memset, memcpy, and memmove, etc all depend on UB.

memset and memcpy read and write padding bytes, which is UB. If you try to say memset/cpy is a "primitive operation", then you're still stuck with the "correct" struct initialization (memset, bzero) being UB if you did something like:

    void f(bool condition) {
      if (condition) {
        struct structwithpadding thing;
        bzero(&thing, sizeof(thing));
      } else {
        printf("wat\n");
      }
    }
The ludicrously broad definition of what UB apparent allows, this can be "optimized" to

    void f(bool condition) {
      printf("wat\n");
    }
Because bzero() writes to padding, and that is UB, which means the condition==true branch "can't happen" \o/

memmove falls to UB much requires pointer comparisons between pointers to different objects, which is UB.

Re: Falsehoods programmers believe about undefined behavior

#158
post #154

I have another falsehood: most programmers believe that people working with C/C++ are constantly battling against UB all day long, five days a week, and that they are irresponsable and careless. That they should live in fear and terror, because "unsafe" is around the corner, and that their programs are not mathematically proven and that they might containt an explotaible bug because, you know, every other C/C++ progr…

An automobile recall is a good analogy here.

Most people driving cars with an active recall are unaffected by the problem the recall is supposed to address. They can drive on blissfully unaware that something could go wrong. They might even enthusiastically recommend that others purchase the car they drive.

For a few people, they'll experience a failure, possibly a dangerous one.

And this is the root of the problem. The fundamental concept of using a language prone to UB exposes all programs to a small risk. In isolation, the risk is small. In aggregate, the problem is real.

Re: Falsehoods programmers believe about undefined behavior

#159

I am always amazed by articles like these. This guy thoroughly covers this topic. I cannot say I have ever written anything that ran into or caused undefined behavior. And I have programmed for a long time. Is this just an interesting topic or do people actively push the compiler to see what it will do? Maybe I am a boring/simple programmer. :)

> I cannot say I have ever written anything that ran into or caused undefined behavior. And I have programmed for a long time.

Perhaps this is true, or perhaps you are just unaware of the undefined behavior you have relied on.

What I can say for sure, is that all of the non-trivial C++ programs written by a large team which I have worked on in my career have invoked some undefined behavior. Usually, the compiler does do "the right thing" despite the error, but sometimes it blows up in our face, and causes incredibly hard to debug bugs, such as a pointer appearing to simultaneously point to two different addresses, because an array was declared as two different sizes in two different translation units.

Even when I spot the instances of undefined behavior, it's often hard to convince other developers that, although this seems to behave correctly now, it could break in unexpected, hard to debug ways at any time in the future.

Re: Falsehoods programmers believe about undefined behavior

#160
post #77

Earlier quoted context omitted.

That is a misconception. "If any step in a program’s execution has undefined behavior, then the entire execution is without meaning. This is important: it’s not that evaluating (1<<32) has an unpredictable result, but rather that the entire execution of a program that evaluates this expression is meaningless. Also, it’s not that the execution is meaningful up to the point where undefined behavior happens: the bad eff…

I agree, but this doesn't refute what I wrote. "If any step in a program’s execution has undefined behavior, then the entire execution is without meaning..." Yes. So UB is a property of a given execition, not a static property of the program itself. I don't argue that you can reason about the behavior of any part of the execution, once it evaluates operations with UB.

once and before.

If a given execution would eventually lead to UB, then it retroactively it cannot be reasoned about.

This time traveling behavior is what is confusing people in thinking that if any execution is UB then all possible executions are UB.

Post reply on HN