Question

Imagine this:

int X;

X = X;

this would be undefined behavior as

1 The behavior is undefined in the following circumstances:

[...]

The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.8, 6.8).

But what about this?

int X;

X;

would the invokation of X; in reference to the quote allow the compiler to cause undefined behavior? Or does this not count as X is "used"?

Was it helpful?

Solution

In C 1999, it is not directly an error to use an uninitialized object. (Your quotes from Annex J are not a normative part of the standard; they are just informative.) An uninitialized object with automatic storage duration has an indeterminate value. For some objects, that value may be a trap representation, so using it may result in undefined behavior.

However, for some objects, it is possible to determine that an uninitialized object cannot have a trap value. For example, an unsigned char cannot have a trap value, and the exact-width signed integer types defined in stdint.h cannot have trap values (because they are two’s complement with no padding bits). For other types, it may be that properties defined by your C implementation cause them not to have trap values. Using an uninitialized int X does not have defined behavior in all C 1999 implementations (but does in some), but using an uninitialized unsigned char X does.

In C 2011, this text was added in 6.3.2 2: “If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.” Therefore, in C 2011, both X = X; and X; have undefined behavior.


History/background:

The C 2011 change supports a Hewlett-Packard machine which has a special flag for certain registers that indicates whether the register contents are valid or not. The machine can generate an exception if a register is used while its contents are invalid. Hence, if the compiler assigns the X of unsigned char X to such a register, using the register when it is invalid may cause an exception in the machine even though there is no unsigned char trap value.

OTHER TIPS

X = X;

The above is undefined behavior. Because X is not initialized. The compiler should at least generate a warning about this.

The standard states 6.3.2.1p2:

If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

However:

X;

The above is similar to:

1212342413;

As X will evaluate to some expression.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top