This type of question and discussion is always a problem, because it requires an interpretation of the C-standard, which in many aspects is not written for clarity, but is rather the result of discussion and compromise between the fact that two (or more) competing factions agree to include in it . After going through this several times, it is clear that much more discussion included what was or was not, included, than ever, where and how to include it in the standard for readability.
Continuing from the comments, I think that we can all agree on the basis of the number of times it was indicated in the comments and answers that Standard C11 (project n1570) § 6.3.2.1 Lvalues, arrays and function pointers apply (¶2)) .
"If , lvalue denotes an automatic storage object of a duration that could be declared in the class register store (its address was never accepted), and this object is uninitialized (not declared with the initializer and not assigned to it, it was executed before use), the behavior is undefined . "
(my emphasis)
The problem arises: "Is an array with automatic storage something that could be declared with a register storage class? "
At first glance, the obvious thought is: "An array with a register storage class specifier? That would be pretty stupid, you can't take the address, how would you ever access the values?" Given § 6.2.5 Types (Comment 36)) "The address of such an object is implicitly used when accessing an array element.
First thoughts are often mistaken, since arrays with automatic storage allow you to use the register storage class. § 6.7.1 (6 and comment 121)
The following code is completely legal - although perhaps not as useful.
#include <stdio.h> int main (void) { register int a[] = { 1, 2, 3, 4 }; register size_t n = sizeof a / sizeof (int); printf ("n : %zu\n", n); return 0; }
The only operators that can be applied to an array declared using the register of storage class specifiers are sizeof and _Alignof . (See § 6.7.1 (comment 121)
Given the foregoing and given any uninitialized element in the array, "uninitialized (not declared with an initializer, and no assignment was made before its use), the behavior is undefined. "
In your particular case:
char c = output[1]; // accesses something "uninitialized"; But is it UB?
output[1] denotes an object with an automatic storage duration that could be declared with a register storage class (its address was never accepted), and this object is not initialized (not declared with the initializer and its assignment is not performed) before use), the behavior is not defined.