++a[j];
Are you saying this behavior is undefined because the elements of the array are uninitialized?
If so, although this is a standard interpretation of clause 4.1 / 1 in the standard, I believe that this is not true. Elements are "uninitialized" in the sense that programmers usually use this term, but I do not believe that this exactly matches the C ++ language specification.
In particular, C ++ 11 8.5 / 11 states that these objects are actually initialized by default, and this seems to me mutually exclusive, since it is not initialized. The standard also states that for some objects that are initialized by default, it means "not initialized." Some may assume that this means that they are uninitialized, but this is not indicated, and I just think that such performance is not required.
The specification clearly states that array elements will have undefined values. C ++ indicates, referring to the C standard, that undefined values โโcan be either valid representations, or legal to access regular, or trap representations. If the specific undefined values โโof the array elements with all of them are real representations (and none of them is INT_MAX, avoiding overflow), then the above line does not cause any undefined behavior in C ++ 11.
Since these elements of the array can be traps, it would be perfectly consistent with the fact that clang would act as if they were guaranteed to be trap representations, effectively choosing the UB code to create optimization opportunities.
Even if clang does not do this, it can still choose to optimize based on the data stream. Klang knows how to do this, as evidenced by the fact that if the inner cycle changes slightly, then the cycles are deleted.
So, why does the (optional) presence of UB seem to optimize optimization when UB is usually seen as an opportunity for more optimization?
What could happen is that clang decided that users want int traps based on the behavior of the equipment. And therefore, instead of using traps as an optimization opportunity, clang should generate code that accurately reproduces the behavior of the program in hardware. This means that loops cannot be excluded based on the data stream, as this can eliminate hardware traps.
C ++ 14 updates the behavior, so that access to the values โโof undefined values โโitself creates undefined behavior, regardless of whether this variable is considered uninitialized or not: