2

From 6.3.2.1 (emphasis mine)

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.

That means, that if the automatic object could not be declared with the register storage class (have it's address taken):

int x; 

printf("just a dummy pointer print %p", &x);  //taking the address to break 6.3.2.1 UB condition

if (x == 2)
{
    print("x uninitialized value: %d", x);
} 

Than according to 6.3.2.1 there is no undefined behavior in if (x == 2) where I use the value of the uninitialized object. If that is true, and there is no UB here, than what is the defined behaviour? what should I expect in x according to the standard?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
izac89
  • 3,790
  • 7
  • 30
  • 46

2 Answers2

2

In this case, because x has had it's address taken, the behavior is not strictly undefined. The value of x at this point is indeterminate. This means the value is either a trap representation or unspecified.

If x happens to contain a trap representation then the behavior is undefined, otherwise the value is unspecified which means that any valid value could be printed.

Also, most systems you're likely to come across don't have any padding bits in integer types, meaning there are no trap representations on that implementation and the value will always be unspecified.

The relevant passages from the C standard:

Section 3.19:

3.19.2

1 indeterminate value either an unspecified value or a trap representation

3.19.3

1 unspecified value valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance

2 NOTE An unspecified value cannot be a trap representation.

3.19.4

1 trap representation an object representation that need not represent a value of the object type

Section 6.7.9p10:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

The Standard uses the term "Undefined Behavior", among other things, to describe general situations where the vast majority of implementations would behave in the same predictable general fashion, but where some particular implementations might serve their customers better by behaving differently.

Consider the following function:

struct foo { unsigned char dat[256]; };

struct foo x,y;

void test(int a, int b)
{
  struct foo temp;
  temp.dat[a] = 1;
  temp.dat[b] = 2;
  x=temp;
  y=temp;
}

I don't think the authors of the Standard wanted to require that programmers fully initialize temp before storing it, but I also don't think they wanted to forbid implementations from simply writing to x.dat[a], y.dat[a], x.dat[b], and y.dat[b], while leaving other elements of those structures holding whatever they'd held previously. Rather than trying to characterize exactly what sorts of optimizations should be allowed, they simply assumed that implementations would seek to best serve their customers' needs.

supercat
  • 77,689
  • 9
  • 166
  • 211