1. 7
  1.  

  2. 3

    A more interesting question is, does the test code shown in the article (comparison of an uninitialized value to itself) invoke undefined behavior?

    1. 1

      yes it does. in this case it’s dereferencing an uninitialized pointer. if we would make the array global/static it would be dereferencing a null pointer.

      1. 1

        This is not correct. Uninitialized static arrays have every element initialized to zero, it’s fine to access any element of them: http://port70.net/~nsz/c/c99/n1256.html#6.7.8p10

        10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then: …

        • if it is an aggregate, every member is initialized (recursively) according to these rules;

        and furthermore

        21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

        Aggregate means struct or array (6.2.5, http://port70.net/~nsz/c/c99/n1256.html#6.2.5p21):

        21 Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.

        1. 3

          The example code shows a non-static (automatic) array with a declaration and no initializer. You’ll note that the sections you quoted refer to what happens when an array (or other aggregate) has fewer items specified in their initializer than the aggregate has members. In this case, there is no initializer. Indeed, this is undefined behavior.

          All the best,

          -HG

          1. 1

            You appear to only have read the 2nd quote in my comment. Here’s the first one again:

            If an object that has static storage duration is not initialized explicitly, then: …

            • if it is an aggregate, every member is initialized (recursively) according to these rules;

            I agree this UB for an array with automatic storage, though.

            1. 1

              @jyn514, the array in the example code is not declared static.

          2. 2

            I stand corrected. in the case that the array has static duration, all elements are indeed initialized to zero. thank you.

            edit: and my whole sentence is wrong. a, the pointer to the head of the array is actually initialized, it is only the array elements that aren’t initialized in the case of automatic duration. so the UB is caused by using the elements and not by dereferencing.

          3. 1

            It has nothing to do with pointers. I’m talking about the uninitialized memory. Would the following code invoke UB ?

            int x;
            if (x == x)
                ...
            

            I do not master the definition of UB, but it seems that if “int” can be initialized with a trap representation (highly unlikely in current implementations), it would be reasonable for this code to crash.

            1. 1

              yes this is UB, as far as the standard is concerned the value of x is indeterminate, and using that value in any form is undefined behaviour.

              from http://port70.net/~nsz/c/c99/n1256.html#J.2:

              The value of an object with automatic storage duration is used while it is indeterminate

        2. 2

          Possibly my favorite C quirk. Saw it in some fun IOCCC entries.