Is it legal for source code containing undefined behavior to crash the compiler?Dividing by zero in a constant expressionDifference between Undefined Behavior and Ill-formed, no diagnostic message requiredWhy are these constructs using pre and post-increment undefined behavior?Undefined, unspecified and implementation-defined behaviorUndefined behavior and sequence pointsA C++ implementation that detects undefined behavior?(Why) is using an uninitialized variable undefined behavior?Can code that is valid in both C and C++ produce different behavior when compiled in each language?Why is f(i = -1, i = -1) undefined behavior?Does undefined behavior apply to asm code?Does the C++ standard allow for an uninitialized bool to crash a program?

ASCII texturing

In-body neutral density (ND) filters?

Fitting data in polar coordinates

When to use Sitecore.Context.Items and why?

Do monthly payments decrease on a mortgage later in the loan?

What does this docker log entry mean?

Co-curricular lessons between geometry and chemistry?

What is White's motivation to give up the Queen?

Outlining the climax made me lose interest in writing the actual story

What is a deductible?

Triangle for a triangle

Has Donald Duck ever had any love interest besides Daisy?

Why does rapeseed oil turn sticky but coconut oil doesn't?

Isn't any conversation with the US president quid-pro-quo?

Was it possible for a message from Paris to reach London within 48 hours in 1782?

Can anyone identify the aircraft in the background of this photo please?

Difference/relationship between power and significance

Is there a text editor that can run shell scripts?

Why is the core ChaCha primitive not good for use in a collision-resistant compression function (crypto hash)?

Should I tell an editor that I believe an article I'm reviewing is not good enough for the journal?

Does 5e have a Manual of the Planes?

how can traditional forms of magic compete against demon magic?

Formula for sum of combinations

Are we sinners because we sin or do we sin because we are sinners?



Is it legal for source code containing undefined behavior to crash the compiler?


Dividing by zero in a constant expressionDifference between Undefined Behavior and Ill-formed, no diagnostic message requiredWhy are these constructs using pre and post-increment undefined behavior?Undefined, unspecified and implementation-defined behaviorUndefined behavior and sequence pointsA C++ implementation that detects undefined behavior?(Why) is using an uninitialized variable undefined behavior?Can code that is valid in both C and C++ produce different behavior when compiled in each language?Why is f(i = -1, i = -1) undefined behavior?Does undefined behavior apply to asm code?Does the C++ standard allow for an uninitialized bool to crash a program?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









82


















Let's say I go to compile some poorly-written C++ source code that invokes undefined behavior, and therefore (as they say) "anything can happen".



From the perspective of what the C++ language specification deems acceptable in a "conformant" compiler, does "anything" in this scenario include the compiler crashing (or stealing my passwords, or otherwise misbehaving or erroring-out at compile-time), or is scope of the undefined-behavior limited specifically to what can happen when the resulting executable runs?










share|improve this question






















  • 22





    "UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

    – Yunnosch
    Aug 26 at 6:37







  • 14





    There's really no limitation, which is the reason it's said that UB can summon nasal demons.

    – Some programmer dude
    Aug 26 at 6:37






  • 15





    UB can make the author post a question on SO. :P

    – Tanveer Badar
    Aug 26 at 6:42






  • 45





    Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

    – john
    Aug 26 at 6:53







  • 9





    @LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

    – Avi Berger
    Aug 26 at 17:42

















82


















Let's say I go to compile some poorly-written C++ source code that invokes undefined behavior, and therefore (as they say) "anything can happen".



From the perspective of what the C++ language specification deems acceptable in a "conformant" compiler, does "anything" in this scenario include the compiler crashing (or stealing my passwords, or otherwise misbehaving or erroring-out at compile-time), or is scope of the undefined-behavior limited specifically to what can happen when the resulting executable runs?










share|improve this question






















  • 22





    "UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

    – Yunnosch
    Aug 26 at 6:37







  • 14





    There's really no limitation, which is the reason it's said that UB can summon nasal demons.

    – Some programmer dude
    Aug 26 at 6:37






  • 15





    UB can make the author post a question on SO. :P

    – Tanveer Badar
    Aug 26 at 6:42






  • 45





    Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

    – john
    Aug 26 at 6:53







  • 9





    @LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

    – Avi Berger
    Aug 26 at 17:42













82













82









82


7






Let's say I go to compile some poorly-written C++ source code that invokes undefined behavior, and therefore (as they say) "anything can happen".



From the perspective of what the C++ language specification deems acceptable in a "conformant" compiler, does "anything" in this scenario include the compiler crashing (or stealing my passwords, or otherwise misbehaving or erroring-out at compile-time), or is scope of the undefined-behavior limited specifically to what can happen when the resulting executable runs?










share|improve this question
















Let's say I go to compile some poorly-written C++ source code that invokes undefined behavior, and therefore (as they say) "anything can happen".



From the perspective of what the C++ language specification deems acceptable in a "conformant" compiler, does "anything" in this scenario include the compiler crashing (or stealing my passwords, or otherwise misbehaving or erroring-out at compile-time), or is scope of the undefined-behavior limited specifically to what can happen when the resulting executable runs?







c++ language-lawyer undefined-behavior






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 29 at 16:03









Benjamin Hodgson

33.2k13 gold badges87 silver badges140 bronze badges




33.2k13 gold badges87 silver badges140 bronze badges










asked Aug 26 at 6:30









Jeremy FriesnerJeremy Friesner

48k11 gold badges89 silver badges176 bronze badges




48k11 gold badges89 silver badges176 bronze badges










  • 22





    "UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

    – Yunnosch
    Aug 26 at 6:37







  • 14





    There's really no limitation, which is the reason it's said that UB can summon nasal demons.

    – Some programmer dude
    Aug 26 at 6:37






  • 15





    UB can make the author post a question on SO. :P

    – Tanveer Badar
    Aug 26 at 6:42






  • 45





    Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

    – john
    Aug 26 at 6:53







  • 9





    @LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

    – Avi Berger
    Aug 26 at 17:42












  • 22





    "UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

    – Yunnosch
    Aug 26 at 6:37







  • 14





    There's really no limitation, which is the reason it's said that UB can summon nasal demons.

    – Some programmer dude
    Aug 26 at 6:37






  • 15





    UB can make the author post a question on SO. :P

    – Tanveer Badar
    Aug 26 at 6:42






  • 45





    Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

    – john
    Aug 26 at 6:53







  • 9





    @LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

    – Avi Berger
    Aug 26 at 17:42







22




22





"UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

– Yunnosch
Aug 26 at 6:37






"UB is UB. Live with it"... No wait. "Please post a MCVE." ... No wait. I love the question for all the reflexes it triggers inappropriatly. :-)

– Yunnosch
Aug 26 at 6:37





14




14





There's really no limitation, which is the reason it's said that UB can summon nasal demons.

– Some programmer dude
Aug 26 at 6:37





There's really no limitation, which is the reason it's said that UB can summon nasal demons.

– Some programmer dude
Aug 26 at 6:37




15




15





UB can make the author post a question on SO. :P

– Tanveer Badar
Aug 26 at 6:42





UB can make the author post a question on SO. :P

– Tanveer Badar
Aug 26 at 6:42




45




45





Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

– john
Aug 26 at 6:53






Irrespective of what the C++ standard says, if I was a compiler writer I would certainly regard it as a bug in my compiler. So if you are seeing this, file a defect report.

– john
Aug 26 at 6:53





9




9





@LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

– Avi Berger
Aug 26 at 17:42





@LeifWillerts This was back in the 80s. I don't remember the exact construct, but think it hinged on using a convoluted variable type. After I put in a replacement I had a "what was I thinking - things don't work that way" moment. I didn't blame the compiler for rejecting the construct, just for rebooting the machine. I doubt anyone would encounter that compiler today. It was the HP C cross compiler for the HP 64000 targeting the 68000 microprocessor.

– Avi Berger
Aug 26 at 17:42












3 Answers
3






active

oldest

votes


















70



















The normative definition of undefined behavior is as follows:




[defns.undefined]



behavior for which this International Standard imposes no requirements



[ Note: Undefined behavior may be expected when this International
Standard omits any explicit definition of behavior or when a program
uses an erroneous construct or erroneous data. Permissible undefined
behavior ranges from ignoring the situation completely with
unpredictable results, to behaving during translation or program
execution in a documented manner characteristic of the environment
(with or without the issuance of a diagnostic message), to terminating
a translation or execution (with the issuance of a diagnostic
message). Many erroneous program constructs do not engender undefined
behavior; they are required to be diagnosed. Evaluation of a constant
expression never exhibits behavior explicitly specified as undefined.
 — end note ]




While the note itself is not normative, it does describe a range of behaviors implementations are known to exhibit. So crashing the compiler (which is translation terminating abruptly), is legitimate according to that note. But really, as the normative text says, the standard doesn't place any bounds for either execution or translation. If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard.






share|improve this answer





















  • 41





    That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

    – Kevin
    Aug 26 at 15:58







  • 66





    Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

    – Ti Strga
    Aug 26 at 18:21







  • 8





    @TiStrga I bet Cthulhu would make an awesome F1 driver.

    – zeta-band
    Aug 26 at 19:21






  • 35





    "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

    – Carmeister
    Aug 26 at 21:36






  • 8





    @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

    – ilkkachu
    Aug 27 at 5:46


















8



















Most kinds of UB that we usually worry about, like NULL-deref or divide by zero, are runtime UB. Compiling a function that would cause runtime UB if executed must not cause the compiler to crash. Unless maybe it can prove that the function (and that path through the function) definitely will be executed by the program.



(2nd thoughts: maybe I haven't considered template / constexpr required evaluation at compile time. Possibly UB during that is allowed to cause arbitrary weirdness during translation even if the resulting function is never called.)



The behaving during translation part of the ISO C++ quote in @StoryTeller's answer is similar to language used in the ISO C standard. C doesn't include templates or constexpr mandatory eval at compile time.



But fun fact: ISO C says in a note that if translation is terminated, it must be with a diagnostic message. Or "behaving during translation ... in a documented manner". I don't think "ignoring the situation completely" could be read as including stopping translation.




Old answer, written before I learned about translation-time UB. It's true for runtime-UB, though, and thus potentially still useful.




There's no such thing as UB that happens at compile time. It can be visible to the compiler along a certain path of execution, but in C++ terms it hasn't happened until execution reaches that path of execution through a function.



Defects in a program that make it impossible to even compile aren't UB, they're syntax errors. Such a program is "not well-formed" in C++ terminology (if I have my standardese correct). A program can be well-formed but contain UB. Difference between Undefined Behavior and Ill-formed, no diagnostic message required



Unless I'm misunderstanding something, ISO C++ requires this program to compile and execute correctly, because execution never reaches the divide by zero. (In practice (Godbolt), good compilers just make working executables. gcc/clang warn about x / 0 but not this, even when optimizing. But anyway, we're trying to tell how low ISO C++ allows quality of implementation to be. So checking gcc/clang is hardly a useful test other than to confirm I wrote the program correctly.)



int cause_UB() 
int x=0;
return 1 / x; // UB if ever reached.
// Note I'm avoiding x/0 in case that counts as translation time UB.
// UB still obvious when optimizing across statements, though.


int main()
if (0)
cause_UB();



A use-case for this might involve the C preprocessor, or constexpr variables and branching on those variables, which leads to nonsense in some paths that are never reached for those choices of constants.



Paths of execution that cause compile-time-visible UB can be assumed to be never take, e.g. a compiler for x86 could emit a ud2 (cause illegal instruction exception) as the definition for cause_UB(). Or within a function, if one side of an if() leads to provable UB, the branch can be removed.



But the compiler still has to compile everything else in a sane and correct way. All paths that don't encounter (or can't be proved to encounter) UB must still be compiled to asm that executes as-if the C++ abstract machine was running it.




You could argue that unconditional compile-time-visible UB in main is an exception to this rule. Or otherwise compile-time-provable that execution starting at main does in fact reach guaranteed UB.



I'd still argue that legal compiler behaviours include producing a grenade that explodes if run. Or more plausibly, a definition of main that consists of a single illegal instruction. I'd argue that if you never run the program, there hasn't been any UB yet. The compiler itself isn't allowed to explode, IMO.




Functions containing possible or provable UB inside branches



UB along any given path of execution reaches backwards in time to "contaminate" all previous code. But in practice compilers can only take advantage of that rule when they can actually prove that paths of execution lead to compile-time-visible UB. e.g.



int minefield(int x) 
if (x == 3)
*(char*)nullptr = x/0;


return x * 5;



The compiler has to make asm that works for all x other than 3, up to the points where x * 5 causes signed-overflow UB at INT_MIN and INT_MAX. If this function is never called with x==3, the program of course contains no UB and must work as written.



We might as well have written if(x == 3) __builtin_unreachable(); in GNU C to tell the compiler that x is definitely not 3.



In practice there's "minefield" code all over the place in normal programs. e.g. any division by an integer promises the compiler that it's non-zero. Any pointer deref promises the compiler that it's non-NULL.






share|improve this answer



































    3



















    What does "legal" mean here? Anything that doesn't contradict the C standard or C++ standard is legal, according to these standards. If you execute a statement i = i++; and as a result dinosaurs take over the world, that doesn't contradict the standards. It does however contradict the laws of physics, so it's not going to happen :-)



    If undefined behaviour crashes your compiler, that doesn't violate the C or C++ standard. It does however mean that the quality of the compiler could (and probably should) be improved.



    In previous versions of the C standard, there were statements that were errors or not dependent on undefined behaviour:



    char* p = 1 / 0;


    Assigning a constant 0 to a char* is allowed. Allowing a non-zero constant is not. Since the value of 1 / 0 is undefined behaviour, it is undefined behaviour whether the compiler should or should not accept this statement. (Nowadays, 1 / 0 does not meet the definition of "integer constant expression" anymore).






    share|improve this answer























    • 3





      To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

      – freakish
      Aug 27 at 8:36













    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );














    draft saved

    draft discarded
















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57652799%2fis-it-legal-for-source-code-containing-undefined-behavior-to-crash-the-compiler%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown


























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    70



















    The normative definition of undefined behavior is as follows:




    [defns.undefined]



    behavior for which this International Standard imposes no requirements



    [ Note: Undefined behavior may be expected when this International
    Standard omits any explicit definition of behavior or when a program
    uses an erroneous construct or erroneous data. Permissible undefined
    behavior ranges from ignoring the situation completely with
    unpredictable results, to behaving during translation or program
    execution in a documented manner characteristic of the environment
    (with or without the issuance of a diagnostic message), to terminating
    a translation or execution (with the issuance of a diagnostic
    message). Many erroneous program constructs do not engender undefined
    behavior; they are required to be diagnosed. Evaluation of a constant
    expression never exhibits behavior explicitly specified as undefined.
     — end note ]




    While the note itself is not normative, it does describe a range of behaviors implementations are known to exhibit. So crashing the compiler (which is translation terminating abruptly), is legitimate according to that note. But really, as the normative text says, the standard doesn't place any bounds for either execution or translation. If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard.






    share|improve this answer





















    • 41





      That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

      – Kevin
      Aug 26 at 15:58







    • 66





      Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

      – Ti Strga
      Aug 26 at 18:21







    • 8





      @TiStrga I bet Cthulhu would make an awesome F1 driver.

      – zeta-band
      Aug 26 at 19:21






    • 35





      "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

      – Carmeister
      Aug 26 at 21:36






    • 8





      @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

      – ilkkachu
      Aug 27 at 5:46















    70



















    The normative definition of undefined behavior is as follows:




    [defns.undefined]



    behavior for which this International Standard imposes no requirements



    [ Note: Undefined behavior may be expected when this International
    Standard omits any explicit definition of behavior or when a program
    uses an erroneous construct or erroneous data. Permissible undefined
    behavior ranges from ignoring the situation completely with
    unpredictable results, to behaving during translation or program
    execution in a documented manner characteristic of the environment
    (with or without the issuance of a diagnostic message), to terminating
    a translation or execution (with the issuance of a diagnostic
    message). Many erroneous program constructs do not engender undefined
    behavior; they are required to be diagnosed. Evaluation of a constant
    expression never exhibits behavior explicitly specified as undefined.
     — end note ]




    While the note itself is not normative, it does describe a range of behaviors implementations are known to exhibit. So crashing the compiler (which is translation terminating abruptly), is legitimate according to that note. But really, as the normative text says, the standard doesn't place any bounds for either execution or translation. If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard.






    share|improve this answer





















    • 41





      That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

      – Kevin
      Aug 26 at 15:58







    • 66





      Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

      – Ti Strga
      Aug 26 at 18:21







    • 8





      @TiStrga I bet Cthulhu would make an awesome F1 driver.

      – zeta-band
      Aug 26 at 19:21






    • 35





      "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

      – Carmeister
      Aug 26 at 21:36






    • 8





      @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

      – ilkkachu
      Aug 27 at 5:46













    70















    70











    70









    The normative definition of undefined behavior is as follows:




    [defns.undefined]



    behavior for which this International Standard imposes no requirements



    [ Note: Undefined behavior may be expected when this International
    Standard omits any explicit definition of behavior or when a program
    uses an erroneous construct or erroneous data. Permissible undefined
    behavior ranges from ignoring the situation completely with
    unpredictable results, to behaving during translation or program
    execution in a documented manner characteristic of the environment
    (with or without the issuance of a diagnostic message), to terminating
    a translation or execution (with the issuance of a diagnostic
    message). Many erroneous program constructs do not engender undefined
    behavior; they are required to be diagnosed. Evaluation of a constant
    expression never exhibits behavior explicitly specified as undefined.
     — end note ]




    While the note itself is not normative, it does describe a range of behaviors implementations are known to exhibit. So crashing the compiler (which is translation terminating abruptly), is legitimate according to that note. But really, as the normative text says, the standard doesn't place any bounds for either execution or translation. If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard.






    share|improve this answer














    The normative definition of undefined behavior is as follows:




    [defns.undefined]



    behavior for which this International Standard imposes no requirements



    [ Note: Undefined behavior may be expected when this International
    Standard omits any explicit definition of behavior or when a program
    uses an erroneous construct or erroneous data. Permissible undefined
    behavior ranges from ignoring the situation completely with
    unpredictable results, to behaving during translation or program
    execution in a documented manner characteristic of the environment
    (with or without the issuance of a diagnostic message), to terminating
    a translation or execution (with the issuance of a diagnostic
    message). Many erroneous program constructs do not engender undefined
    behavior; they are required to be diagnosed. Evaluation of a constant
    expression never exhibits behavior explicitly specified as undefined.
     — end note ]




    While the note itself is not normative, it does describe a range of behaviors implementations are known to exhibit. So crashing the compiler (which is translation terminating abruptly), is legitimate according to that note. But really, as the normative text says, the standard doesn't place any bounds for either execution or translation. If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard.







    share|improve this answer













    share|improve this answer




    share|improve this answer










    answered Aug 26 at 6:39









    StoryTeller - Unslander MonicaStoryTeller - Unslander Monica

    125k19 gold badges270 silver badges335 bronze badges




    125k19 gold badges270 silver badges335 bronze badges










    • 41





      That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

      – Kevin
      Aug 26 at 15:58







    • 66





      Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

      – Ti Strga
      Aug 26 at 18:21







    • 8





      @TiStrga I bet Cthulhu would make an awesome F1 driver.

      – zeta-band
      Aug 26 at 19:21






    • 35





      "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

      – Carmeister
      Aug 26 at 21:36






    • 8





      @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

      – ilkkachu
      Aug 27 at 5:46












    • 41





      That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

      – Kevin
      Aug 26 at 15:58







    • 66





      Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

      – Ti Strga
      Aug 26 at 18:21







    • 8





      @TiStrga I bet Cthulhu would make an awesome F1 driver.

      – zeta-band
      Aug 26 at 19:21






    • 35





      "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

      – Carmeister
      Aug 26 at 21:36






    • 8





      @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

      – ilkkachu
      Aug 27 at 5:46







    41




    41





    That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

    – Kevin
    Aug 26 at 15:58






    That said, if you can actually get a compiler to execute arbitrary code at compile-time, without any sandboxing, then various security people would be very interested to know about it. The same goes for segfaulting the compiler.

    – Kevin
    Aug 26 at 15:58





    66




    66





    Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

    – Ti Strga
    Aug 26 at 18:21






    Ditto for what Kevin said. As a C/C++/etc compiler engineer in a previous career, our position was that undefined behavior could crash your program, screw up your output data, set your house on fire, whatever. But the compiler should never crash no matter what the input. (It might not give helpful error messages, but it should produce some kind of diagnostic and exit rather than just screaming CTHULHU TAKE THE WHEEL and segfaulting.)

    – Ti Strga
    Aug 26 at 18:21





    8




    8





    @TiStrga I bet Cthulhu would make an awesome F1 driver.

    – zeta-band
    Aug 26 at 19:21





    @TiStrga I bet Cthulhu would make an awesome F1 driver.

    – zeta-band
    Aug 26 at 19:21




    35




    35





    "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

    – Carmeister
    Aug 26 at 21:36





    "If an implementation steals your passwords, it's not a violation of any contract laid forth in the standard." That's true regardless of whether the code has UB though, isn't it? The standard only dictates what the compiled program should do - a compiler that correctly compiles the code but steals your passwords in the process wouldn't be disobeying the standard.

    – Carmeister
    Aug 26 at 21:36




    8




    8





    @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

    – ilkkachu
    Aug 27 at 5:46





    @Carmeister, oooh, that's a good point, I'll make sure to remind people of that whenever those "UB gives the compiler permission to start a nuclear war" arguments pop up. Again.

    – ilkkachu
    Aug 27 at 5:46













    8



















    Most kinds of UB that we usually worry about, like NULL-deref or divide by zero, are runtime UB. Compiling a function that would cause runtime UB if executed must not cause the compiler to crash. Unless maybe it can prove that the function (and that path through the function) definitely will be executed by the program.



    (2nd thoughts: maybe I haven't considered template / constexpr required evaluation at compile time. Possibly UB during that is allowed to cause arbitrary weirdness during translation even if the resulting function is never called.)



    The behaving during translation part of the ISO C++ quote in @StoryTeller's answer is similar to language used in the ISO C standard. C doesn't include templates or constexpr mandatory eval at compile time.



    But fun fact: ISO C says in a note that if translation is terminated, it must be with a diagnostic message. Or "behaving during translation ... in a documented manner". I don't think "ignoring the situation completely" could be read as including stopping translation.




    Old answer, written before I learned about translation-time UB. It's true for runtime-UB, though, and thus potentially still useful.




    There's no such thing as UB that happens at compile time. It can be visible to the compiler along a certain path of execution, but in C++ terms it hasn't happened until execution reaches that path of execution through a function.



    Defects in a program that make it impossible to even compile aren't UB, they're syntax errors. Such a program is "not well-formed" in C++ terminology (if I have my standardese correct). A program can be well-formed but contain UB. Difference between Undefined Behavior and Ill-formed, no diagnostic message required



    Unless I'm misunderstanding something, ISO C++ requires this program to compile and execute correctly, because execution never reaches the divide by zero. (In practice (Godbolt), good compilers just make working executables. gcc/clang warn about x / 0 but not this, even when optimizing. But anyway, we're trying to tell how low ISO C++ allows quality of implementation to be. So checking gcc/clang is hardly a useful test other than to confirm I wrote the program correctly.)



    int cause_UB() 
    int x=0;
    return 1 / x; // UB if ever reached.
    // Note I'm avoiding x/0 in case that counts as translation time UB.
    // UB still obvious when optimizing across statements, though.


    int main()
    if (0)
    cause_UB();



    A use-case for this might involve the C preprocessor, or constexpr variables and branching on those variables, which leads to nonsense in some paths that are never reached for those choices of constants.



    Paths of execution that cause compile-time-visible UB can be assumed to be never take, e.g. a compiler for x86 could emit a ud2 (cause illegal instruction exception) as the definition for cause_UB(). Or within a function, if one side of an if() leads to provable UB, the branch can be removed.



    But the compiler still has to compile everything else in a sane and correct way. All paths that don't encounter (or can't be proved to encounter) UB must still be compiled to asm that executes as-if the C++ abstract machine was running it.




    You could argue that unconditional compile-time-visible UB in main is an exception to this rule. Or otherwise compile-time-provable that execution starting at main does in fact reach guaranteed UB.



    I'd still argue that legal compiler behaviours include producing a grenade that explodes if run. Or more plausibly, a definition of main that consists of a single illegal instruction. I'd argue that if you never run the program, there hasn't been any UB yet. The compiler itself isn't allowed to explode, IMO.




    Functions containing possible or provable UB inside branches



    UB along any given path of execution reaches backwards in time to "contaminate" all previous code. But in practice compilers can only take advantage of that rule when they can actually prove that paths of execution lead to compile-time-visible UB. e.g.



    int minefield(int x) 
    if (x == 3)
    *(char*)nullptr = x/0;


    return x * 5;



    The compiler has to make asm that works for all x other than 3, up to the points where x * 5 causes signed-overflow UB at INT_MIN and INT_MAX. If this function is never called with x==3, the program of course contains no UB and must work as written.



    We might as well have written if(x == 3) __builtin_unreachable(); in GNU C to tell the compiler that x is definitely not 3.



    In practice there's "minefield" code all over the place in normal programs. e.g. any division by an integer promises the compiler that it's non-zero. Any pointer deref promises the compiler that it's non-NULL.






    share|improve this answer
































      8



















      Most kinds of UB that we usually worry about, like NULL-deref or divide by zero, are runtime UB. Compiling a function that would cause runtime UB if executed must not cause the compiler to crash. Unless maybe it can prove that the function (and that path through the function) definitely will be executed by the program.



      (2nd thoughts: maybe I haven't considered template / constexpr required evaluation at compile time. Possibly UB during that is allowed to cause arbitrary weirdness during translation even if the resulting function is never called.)



      The behaving during translation part of the ISO C++ quote in @StoryTeller's answer is similar to language used in the ISO C standard. C doesn't include templates or constexpr mandatory eval at compile time.



      But fun fact: ISO C says in a note that if translation is terminated, it must be with a diagnostic message. Or "behaving during translation ... in a documented manner". I don't think "ignoring the situation completely" could be read as including stopping translation.




      Old answer, written before I learned about translation-time UB. It's true for runtime-UB, though, and thus potentially still useful.




      There's no such thing as UB that happens at compile time. It can be visible to the compiler along a certain path of execution, but in C++ terms it hasn't happened until execution reaches that path of execution through a function.



      Defects in a program that make it impossible to even compile aren't UB, they're syntax errors. Such a program is "not well-formed" in C++ terminology (if I have my standardese correct). A program can be well-formed but contain UB. Difference between Undefined Behavior and Ill-formed, no diagnostic message required



      Unless I'm misunderstanding something, ISO C++ requires this program to compile and execute correctly, because execution never reaches the divide by zero. (In practice (Godbolt), good compilers just make working executables. gcc/clang warn about x / 0 but not this, even when optimizing. But anyway, we're trying to tell how low ISO C++ allows quality of implementation to be. So checking gcc/clang is hardly a useful test other than to confirm I wrote the program correctly.)



      int cause_UB() 
      int x=0;
      return 1 / x; // UB if ever reached.
      // Note I'm avoiding x/0 in case that counts as translation time UB.
      // UB still obvious when optimizing across statements, though.


      int main()
      if (0)
      cause_UB();



      A use-case for this might involve the C preprocessor, or constexpr variables and branching on those variables, which leads to nonsense in some paths that are never reached for those choices of constants.



      Paths of execution that cause compile-time-visible UB can be assumed to be never take, e.g. a compiler for x86 could emit a ud2 (cause illegal instruction exception) as the definition for cause_UB(). Or within a function, if one side of an if() leads to provable UB, the branch can be removed.



      But the compiler still has to compile everything else in a sane and correct way. All paths that don't encounter (or can't be proved to encounter) UB must still be compiled to asm that executes as-if the C++ abstract machine was running it.




      You could argue that unconditional compile-time-visible UB in main is an exception to this rule. Or otherwise compile-time-provable that execution starting at main does in fact reach guaranteed UB.



      I'd still argue that legal compiler behaviours include producing a grenade that explodes if run. Or more plausibly, a definition of main that consists of a single illegal instruction. I'd argue that if you never run the program, there hasn't been any UB yet. The compiler itself isn't allowed to explode, IMO.




      Functions containing possible or provable UB inside branches



      UB along any given path of execution reaches backwards in time to "contaminate" all previous code. But in practice compilers can only take advantage of that rule when they can actually prove that paths of execution lead to compile-time-visible UB. e.g.



      int minefield(int x) 
      if (x == 3)
      *(char*)nullptr = x/0;


      return x * 5;



      The compiler has to make asm that works for all x other than 3, up to the points where x * 5 causes signed-overflow UB at INT_MIN and INT_MAX. If this function is never called with x==3, the program of course contains no UB and must work as written.



      We might as well have written if(x == 3) __builtin_unreachable(); in GNU C to tell the compiler that x is definitely not 3.



      In practice there's "minefield" code all over the place in normal programs. e.g. any division by an integer promises the compiler that it's non-zero. Any pointer deref promises the compiler that it's non-NULL.






      share|improve this answer






























        8















        8











        8









        Most kinds of UB that we usually worry about, like NULL-deref or divide by zero, are runtime UB. Compiling a function that would cause runtime UB if executed must not cause the compiler to crash. Unless maybe it can prove that the function (and that path through the function) definitely will be executed by the program.



        (2nd thoughts: maybe I haven't considered template / constexpr required evaluation at compile time. Possibly UB during that is allowed to cause arbitrary weirdness during translation even if the resulting function is never called.)



        The behaving during translation part of the ISO C++ quote in @StoryTeller's answer is similar to language used in the ISO C standard. C doesn't include templates or constexpr mandatory eval at compile time.



        But fun fact: ISO C says in a note that if translation is terminated, it must be with a diagnostic message. Or "behaving during translation ... in a documented manner". I don't think "ignoring the situation completely" could be read as including stopping translation.




        Old answer, written before I learned about translation-time UB. It's true for runtime-UB, though, and thus potentially still useful.




        There's no such thing as UB that happens at compile time. It can be visible to the compiler along a certain path of execution, but in C++ terms it hasn't happened until execution reaches that path of execution through a function.



        Defects in a program that make it impossible to even compile aren't UB, they're syntax errors. Such a program is "not well-formed" in C++ terminology (if I have my standardese correct). A program can be well-formed but contain UB. Difference between Undefined Behavior and Ill-formed, no diagnostic message required



        Unless I'm misunderstanding something, ISO C++ requires this program to compile and execute correctly, because execution never reaches the divide by zero. (In practice (Godbolt), good compilers just make working executables. gcc/clang warn about x / 0 but not this, even when optimizing. But anyway, we're trying to tell how low ISO C++ allows quality of implementation to be. So checking gcc/clang is hardly a useful test other than to confirm I wrote the program correctly.)



        int cause_UB() 
        int x=0;
        return 1 / x; // UB if ever reached.
        // Note I'm avoiding x/0 in case that counts as translation time UB.
        // UB still obvious when optimizing across statements, though.


        int main()
        if (0)
        cause_UB();



        A use-case for this might involve the C preprocessor, or constexpr variables and branching on those variables, which leads to nonsense in some paths that are never reached for those choices of constants.



        Paths of execution that cause compile-time-visible UB can be assumed to be never take, e.g. a compiler for x86 could emit a ud2 (cause illegal instruction exception) as the definition for cause_UB(). Or within a function, if one side of an if() leads to provable UB, the branch can be removed.



        But the compiler still has to compile everything else in a sane and correct way. All paths that don't encounter (or can't be proved to encounter) UB must still be compiled to asm that executes as-if the C++ abstract machine was running it.




        You could argue that unconditional compile-time-visible UB in main is an exception to this rule. Or otherwise compile-time-provable that execution starting at main does in fact reach guaranteed UB.



        I'd still argue that legal compiler behaviours include producing a grenade that explodes if run. Or more plausibly, a definition of main that consists of a single illegal instruction. I'd argue that if you never run the program, there hasn't been any UB yet. The compiler itself isn't allowed to explode, IMO.




        Functions containing possible or provable UB inside branches



        UB along any given path of execution reaches backwards in time to "contaminate" all previous code. But in practice compilers can only take advantage of that rule when they can actually prove that paths of execution lead to compile-time-visible UB. e.g.



        int minefield(int x) 
        if (x == 3)
        *(char*)nullptr = x/0;


        return x * 5;



        The compiler has to make asm that works for all x other than 3, up to the points where x * 5 causes signed-overflow UB at INT_MIN and INT_MAX. If this function is never called with x==3, the program of course contains no UB and must work as written.



        We might as well have written if(x == 3) __builtin_unreachable(); in GNU C to tell the compiler that x is definitely not 3.



        In practice there's "minefield" code all over the place in normal programs. e.g. any division by an integer promises the compiler that it's non-zero. Any pointer deref promises the compiler that it's non-NULL.






        share|improve this answer
















        Most kinds of UB that we usually worry about, like NULL-deref or divide by zero, are runtime UB. Compiling a function that would cause runtime UB if executed must not cause the compiler to crash. Unless maybe it can prove that the function (and that path through the function) definitely will be executed by the program.



        (2nd thoughts: maybe I haven't considered template / constexpr required evaluation at compile time. Possibly UB during that is allowed to cause arbitrary weirdness during translation even if the resulting function is never called.)



        The behaving during translation part of the ISO C++ quote in @StoryTeller's answer is similar to language used in the ISO C standard. C doesn't include templates or constexpr mandatory eval at compile time.



        But fun fact: ISO C says in a note that if translation is terminated, it must be with a diagnostic message. Or "behaving during translation ... in a documented manner". I don't think "ignoring the situation completely" could be read as including stopping translation.




        Old answer, written before I learned about translation-time UB. It's true for runtime-UB, though, and thus potentially still useful.




        There's no such thing as UB that happens at compile time. It can be visible to the compiler along a certain path of execution, but in C++ terms it hasn't happened until execution reaches that path of execution through a function.



        Defects in a program that make it impossible to even compile aren't UB, they're syntax errors. Such a program is "not well-formed" in C++ terminology (if I have my standardese correct). A program can be well-formed but contain UB. Difference between Undefined Behavior and Ill-formed, no diagnostic message required



        Unless I'm misunderstanding something, ISO C++ requires this program to compile and execute correctly, because execution never reaches the divide by zero. (In practice (Godbolt), good compilers just make working executables. gcc/clang warn about x / 0 but not this, even when optimizing. But anyway, we're trying to tell how low ISO C++ allows quality of implementation to be. So checking gcc/clang is hardly a useful test other than to confirm I wrote the program correctly.)



        int cause_UB() 
        int x=0;
        return 1 / x; // UB if ever reached.
        // Note I'm avoiding x/0 in case that counts as translation time UB.
        // UB still obvious when optimizing across statements, though.


        int main()
        if (0)
        cause_UB();



        A use-case for this might involve the C preprocessor, or constexpr variables and branching on those variables, which leads to nonsense in some paths that are never reached for those choices of constants.



        Paths of execution that cause compile-time-visible UB can be assumed to be never take, e.g. a compiler for x86 could emit a ud2 (cause illegal instruction exception) as the definition for cause_UB(). Or within a function, if one side of an if() leads to provable UB, the branch can be removed.



        But the compiler still has to compile everything else in a sane and correct way. All paths that don't encounter (or can't be proved to encounter) UB must still be compiled to asm that executes as-if the C++ abstract machine was running it.




        You could argue that unconditional compile-time-visible UB in main is an exception to this rule. Or otherwise compile-time-provable that execution starting at main does in fact reach guaranteed UB.



        I'd still argue that legal compiler behaviours include producing a grenade that explodes if run. Or more plausibly, a definition of main that consists of a single illegal instruction. I'd argue that if you never run the program, there hasn't been any UB yet. The compiler itself isn't allowed to explode, IMO.




        Functions containing possible or provable UB inside branches



        UB along any given path of execution reaches backwards in time to "contaminate" all previous code. But in practice compilers can only take advantage of that rule when they can actually prove that paths of execution lead to compile-time-visible UB. e.g.



        int minefield(int x) 
        if (x == 3)
        *(char*)nullptr = x/0;


        return x * 5;



        The compiler has to make asm that works for all x other than 3, up to the points where x * 5 causes signed-overflow UB at INT_MIN and INT_MAX. If this function is never called with x==3, the program of course contains no UB and must work as written.



        We might as well have written if(x == 3) __builtin_unreachable(); in GNU C to tell the compiler that x is definitely not 3.



        In practice there's "minefield" code all over the place in normal programs. e.g. any division by an integer promises the compiler that it's non-zero. Any pointer deref promises the compiler that it's non-NULL.







        share|improve this answer















        share|improve this answer




        share|improve this answer








        edited Aug 27 at 11:28

























        answered Aug 27 at 10:32









        Peter CordesPeter Cordes

        167k26 gold badges263 silver badges420 bronze badges




        167k26 gold badges263 silver badges420 bronze badges
























            3



















            What does "legal" mean here? Anything that doesn't contradict the C standard or C++ standard is legal, according to these standards. If you execute a statement i = i++; and as a result dinosaurs take over the world, that doesn't contradict the standards. It does however contradict the laws of physics, so it's not going to happen :-)



            If undefined behaviour crashes your compiler, that doesn't violate the C or C++ standard. It does however mean that the quality of the compiler could (and probably should) be improved.



            In previous versions of the C standard, there were statements that were errors or not dependent on undefined behaviour:



            char* p = 1 / 0;


            Assigning a constant 0 to a char* is allowed. Allowing a non-zero constant is not. Since the value of 1 / 0 is undefined behaviour, it is undefined behaviour whether the compiler should or should not accept this statement. (Nowadays, 1 / 0 does not meet the definition of "integer constant expression" anymore).






            share|improve this answer























            • 3





              To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

              – freakish
              Aug 27 at 8:36
















            3



















            What does "legal" mean here? Anything that doesn't contradict the C standard or C++ standard is legal, according to these standards. If you execute a statement i = i++; and as a result dinosaurs take over the world, that doesn't contradict the standards. It does however contradict the laws of physics, so it's not going to happen :-)



            If undefined behaviour crashes your compiler, that doesn't violate the C or C++ standard. It does however mean that the quality of the compiler could (and probably should) be improved.



            In previous versions of the C standard, there were statements that were errors or not dependent on undefined behaviour:



            char* p = 1 / 0;


            Assigning a constant 0 to a char* is allowed. Allowing a non-zero constant is not. Since the value of 1 / 0 is undefined behaviour, it is undefined behaviour whether the compiler should or should not accept this statement. (Nowadays, 1 / 0 does not meet the definition of "integer constant expression" anymore).






            share|improve this answer























            • 3





              To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

              – freakish
              Aug 27 at 8:36














            3















            3











            3









            What does "legal" mean here? Anything that doesn't contradict the C standard or C++ standard is legal, according to these standards. If you execute a statement i = i++; and as a result dinosaurs take over the world, that doesn't contradict the standards. It does however contradict the laws of physics, so it's not going to happen :-)



            If undefined behaviour crashes your compiler, that doesn't violate the C or C++ standard. It does however mean that the quality of the compiler could (and probably should) be improved.



            In previous versions of the C standard, there were statements that were errors or not dependent on undefined behaviour:



            char* p = 1 / 0;


            Assigning a constant 0 to a char* is allowed. Allowing a non-zero constant is not. Since the value of 1 / 0 is undefined behaviour, it is undefined behaviour whether the compiler should or should not accept this statement. (Nowadays, 1 / 0 does not meet the definition of "integer constant expression" anymore).






            share|improve this answer
















            What does "legal" mean here? Anything that doesn't contradict the C standard or C++ standard is legal, according to these standards. If you execute a statement i = i++; and as a result dinosaurs take over the world, that doesn't contradict the standards. It does however contradict the laws of physics, so it's not going to happen :-)



            If undefined behaviour crashes your compiler, that doesn't violate the C or C++ standard. It does however mean that the quality of the compiler could (and probably should) be improved.



            In previous versions of the C standard, there were statements that were errors or not dependent on undefined behaviour:



            char* p = 1 / 0;


            Assigning a constant 0 to a char* is allowed. Allowing a non-zero constant is not. Since the value of 1 / 0 is undefined behaviour, it is undefined behaviour whether the compiler should or should not accept this statement. (Nowadays, 1 / 0 does not meet the definition of "integer constant expression" anymore).







            share|improve this answer















            share|improve this answer




            share|improve this answer








            edited Aug 26 at 20:27









            amalloy

            65.7k7 gold badges117 silver badges171 bronze badges




            65.7k7 gold badges117 silver badges171 bronze badges










            answered Aug 26 at 16:22









            gnasher729gnasher729

            43.7k4 gold badges55 silver badges83 bronze badges




            43.7k4 gold badges55 silver badges83 bronze badges










            • 3





              To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

              – freakish
              Aug 27 at 8:36













            • 3





              To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

              – freakish
              Aug 27 at 8:36








            3




            3





            To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

            – freakish
            Aug 27 at 8:36






            To be precise: dinosaurs taking over the world does not contradict any laws of physics (e.g. Jurassic Park variation). It's just highly unlikely. :)

            – freakish
            Aug 27 at 8:36



















            draft saved

            draft discarded















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57652799%2fis-it-legal-for-source-code-containing-undefined-behavior-to-crash-the-compiler%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown









            Popular posts from this blog

            Tamil (spriik) Luke uk diar | Nawigatjuun

            Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

            Where does the image of a data connector as a sharp metal spike originate from?Where does the concept of infected people turning into zombies only after death originate from?Where does the motif of a reanimated human head originate?Where did the notion that Dragons could speak originate?Where does the archetypal image of the 'Grey' alien come from?Where did the suffix '-Man' originate?Where does the notion of being injured or killed by an illusion originate?Where did the term “sophont” originate?Where does the trope of magic spells being driven by advanced technology originate from?Where did the term “the living impaired” originate?