Issue 1112: Undefined behavior from uninitialized reads

Authors: Jay Ghiron
Date: 2026-09-18
Submitted against: C23
Status: Open
Cross-references: 0338

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.

(C23 6.3.3.1 "Lvalues, arrays, and function designators" paragraph 2.)

This definition of uninitialized has many issues. First:

struct S{int x;};
int main(){
struct S s;
s.x=0;
struct S t=s;
}

This appears to be undefined behavior because the address of s was never taken, s does not have an initializer, and no assignment to s has been done. Surely it is not intended for this to be undefined. The reverse scenario of assigning to a whole structure but never directly assigning to a member appears to be fine, assigning to a structure will assign to all members (recursively) as far as I understand. The following seem to be permitted even though the intent is probably to not allow them:

int main(){
goto l;
char a=0;
l:/* initialization skipped */
char b=a;/* not uninitialized from this wording */
}
int main(){
char c=c;/* not uninitialized from this wording */
}
int main(){
goto m;
n:
char d;/* indeterminate again */
char e=d;/* not uninitialized from this wording */
return 0;
m:
d=0;/* assignment to d */
goto n;
}
int main(){
char f,g;
f=*&g;/* assignment to indeterminate value */
char h=f;/* not uninitialized from this wording */
}

Note that char does not have any non-value representations so it is valid to copy an indeterminate value. The wording has been adjusted in C2Y, but the meaning of uninitialized was not changed.