At what point in the loop does integer overflow become undefined behavior?

后端 未结 12 2235
南方客
南方客 2020-12-07 18:12

This is an example to illustrate my question which involves some much more complicated code that I can\'t post here.

#include 
int main()
{
           


        
12条回答
  •  眼角桃花
    2020-12-07 18:45

    Since this question is dual tagged C and C++ I will try and address both. C and C++ take different approaches here.

    In C the implementation must be able to prove the undefined behavior will be invoked in order to treat the whole program as-if it had undefined behavior. In the OPs example it would seem trivial for the compiler to prove that and therefore it is as-if the whole program was undefined.

    We can see this from Defect Report 109 which at its crux asks:

    If however the C Standard recognizes the separate existence of "undefined values" (whose mere creation does not involve wholly "undefined behavior") then a person doing compiler testing could write a test case such as the following, and he/she could also expect (or possibly demand) that a conforming implementation should, at the very least, compile this code (and possibly also allow it to execute) without "failure."

    int array1[5];
    int array2[5];
    int *p1 = &array1[0];
    int *p2 = &array2[0];
    
    int foo()
    {
    int i;
    i = (p1 > p2); /* Must this be "successfully translated"? */
    1/0; /* Must this be "successfully translated"? */
    return 0;
    }
    

    So the bottom line question is this: Must the above code be "successfully translated" (whatever that means)? (See the footnote attached to subclause 5.1.1.3.)

    and the response was:

    The C Standard uses the term "indeterminately valued" not "undefined value." Use of an indeterminate valued object results in undefined behavior. The footnote to subclause 5.1.1.3 points out that an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. If an expression whose evaulation would result in undefined behavior appears in a context where a constant expression is required, the containing program is not strictly conforming. Furthermore, if every possible execution of a given program would result in undefined behavior, the given program is not strictly conforming. A conforming implementation must not fail to translate a strictly conforming program simply because some possible execution of that program would result in undefined behavior. Because foo might never be called, the example given must be successfully translated by a conforming implementation.

    In C++ the approach seems more relaxed and would suggest a program has undefined behavior regardless of whether the implementation can prove it statically or not.

    We have [intro.abstrac]p5 which says:

    A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this document places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

提交回复
热议问题