1 << undefined_behaviour



  • @NedFodder said:

    but that's beside the point.

    Making @blakeyrat complain is never beside the point.


  • Discourse touched me in a no-no place

    @ben_lubar said:

    It can send demons flying out of your nasal cavities if it wants to.

    It's long past time to retire this silly saying.


  • Discourse touched me in a no-no place

    Be aware that flying out of your nose is only Phase 1. The demons can fly other places, and might bring something large and purple with them. Beware!


  • Notification Spam Recipient

    @FrostCat said:

    It's long past time to retire this silly saying.

    Is it up for re-hire? I have no idea the context behind this colloquialism.


  • Discourse touched me in a no-no place

    @Tsaukpaetra said:

    @FrostCat said:
    It's long past time to retire this silly saying.

    Is it up for re-hire? I have no idea the context behind this colloquialism.

    Some wag, long ago, said that invoking UB in C is treading in uncharted waters. The compiler can do anything it wants, like erase your hard drive or cause demons to fly out your nose. Yes, yes, it was probably funny the first few hundred times, but it's time to find a new joke.

    The shorter version is, watch the SpongeBob Squarepants episode "Ripped Pants".


  • Notification Spam Recipient

    Ah.

    @FrostCat said:

    like erase your hard drive

    Ooh! Now I kinda want to write a virus that compiles your code instead!

    No, wait, that sounds like a terrible idea that someone probably already has been done before.


  • Banned

    @FrostCat said:

    Yes, yes, it was probably funny the first few hundred times, but it's time to find a new joke.

    The point isn't to be funny; the point is to communicate the idea in a way that everyone except @blakeyrat will understand - and the phrase "nasal demons" does just that.



  • [quote="ben_lubar, post:35, topic:53531]
    Declaring it volatile would just mean it has to do the load and the store. The shifts are effectively a no-op, so it could omit those.[/quote]

    No it can't. By definition, the compiler can not make such assumptions with a volatile variable because there may be side-effects to the shifts that it doesn't know about - that's the reason volatile exists.

    [quote="ben_lubar, post:35, topic:53531]
    Also, once you invoke undefined behavior, the compiler is allowed to do literally anything. It can send demons flying out of your nasal cavities if it wants to. "It would probably do what you want" is nothing, because with undefined behavior, it can also delete your OS and then print "sausage slaps" 1000 times.
    [/quote]

    If this was comp.lang.c and we were talking about portable code, I'd agree with you. But if you're talking about code that is going to compile and run on exactly one platform, then no. UB doesn't mean random. The machine language isn't going to change every time you run the program. And some implementations may define a behavior even if ISO doesn't. You can compile and run it, and if it works, use it. You just have to be aware that any change to the build environment (different compiler, different optimization flags, etc.) may break it. Bad for a portable code and source-code distributions. Possibly acceptable for a binary distribution of code with a well-defined and not-likely-to-change build environment.


  • Discourse touched me in a no-no place

    @Gaska said:

    The point isn't to be funny

    I assure you humor was involved. Else the example would be "the compiler is free to insert a call to exit(0) at the point of the UB" or something similarly dry.


  • Winner of the 2016 Presidential Election

    @David_C said:

    UB doesn't mean random. The machine language isn't going to change every time you run the program. And some implementations may define a behavior even if ISO doesn't.

    I disagree. Relying on "implementation-defined" behavior might be defensible in some cases, since it's basically the same as relying on compiler-specific/platform-specific extensions or behavior. Relying on undefined behavior? That's just dangerous, and a really bad practical decision. There is a good chance it only works with specific compile options and a specific minor version of the compiler, maybe even only under specific circumstances which you may not fully understand. At some point, you're going to have to upgrade your compiler or change the compile flags for some reason, and then you may be fucked.



  • @asdf said:

    Relying on "implementation-defined" behavior might be defensible in some cases, since it's basically the same as relying on compiler-specific/platform-specific extensions or behavior ...

    I believe I said that:

    @David_C said:

    You just have to be aware that any change to the build environment (different compiler, different optimization flags, etc.) may break it. Bad for a portable code and source-code distributions. Possibly acceptable for a binary distribution of code with a well-defined and not-likely-to-change build environment.


  • Discourse touched me in a no-no place

    The C specification goes massively out of its way to not assume that it is being executed on a 2's-complement binary fixed-width field system; there are a few operations where those things sneak through slightly, but they're really sparse. (I don't think anything challenges the binary assumption.) It therefore leaves a lot of stuff in the space of implementation-defined and undefined.

    Implementations are free to constrain that space. The C standard does not require the compiler to refuse to compile such things. Theoretically, a compiler could go the whole nasal demons route if you shift a 1 off the end. Theoretically, a compiler writer who made such a thing actually happen could survive the lynchmob. Theoretically.

    Practically, what actually happens is that optimizing compilers are actually damn careful about this sort of thing. Shifts by constant amounts are subject to aggressive optimization, especially if the value being shifted is also knowable, but shifts by variable amounts are usually left alone. It's possible for the front-end to assert that “nothing bad will happen” and enable the really aggressive stuff, but it's not usually done because it doesn't save much and it can have observable consequences.

    But what do I know? I'm just writing an optimizing compiler. For fun.
    Nurse! I want to go back to my nice room now, with those lovely soft walls.


  • Notification Spam Recipient

    @dkf said:

    my nice room now, with those lovely soft walls.

    Lucky! My room's walls are made of serrated bricks! You do NOT want to try cuddling up with that more than once!



  • @Gaska said:

    Since calling BS has no side effects, your whole post has been optimized away.

    Also, programs that never terminate are also undefined behavior, and so the entire program can be optimized away.


  • Garbage Person

    From memory, but GCC's implementation defined behavior upon encountering a #pragma used to be something like replacing the compiler process with nethack.



  • GCC 1.17, according to this blog post.



  • @jmp said:

    Also, programs that never terminate are also undefined behavior, and so the entire program can be optimized away.

    Yes, but you first have to figure out whether the program will ever terminate.



  • It will, because you optimized it away.


  • Banned

    @jmp said:

    Also, programs that never terminate are also undefined behavior

    They're not.

    @jmp said:

    and so the entire program can be optimized away.

    Only in specific circumstances that are unrelated to undefined behavior.



  • The implementation may assume that any thread will eventually do one of the following:

    • terminate
    • make a call to a library I/O function
    • access or modify a volatile object, or
    • perform a synchronization operation or an atomic operation.

    IIRC calling a function doesn't necessarily do any of these; we would have to know the definition of BS().

    This blog post, linked from that Stack Overflow answer, is also a good description.


  • Banned

    IANAL, so I can't really tell if code that acts against the exceptations that the compiler might or might not have is the same as undefined behavior (my bet is that it's not), but you don't need these to make infinite loops optimizable. The "as-if rule" is enough:

    1.9.8. The least requirements on a conforming implementation are:
    — Access to volatile objects are evaluated strictly according to the rules of the abstract machine.
    — At program termination, all data written into files shall be identical to one of the possible results that
    execution of the program according to the abstract semantics would have produced.
    — The input and output dynamics of interactive devices shall take place in such a fashion that prompting
    output is actually delivered before a program waits for input. What constitutes an interactive device
    is implementation-defined.



  • @ben_lubar said:

    It will, because you optimized it away.

    Optimize first, ask questions later.



  • My favorite type of optimizing compiler is the kind that's only right sometimes, because that is the set consisting of all possible programs.


Log in to reply