The following code attempts to use array indexing on a string literal in two different constant contexts:
static char x = "abcx"[3];
_Static_assert ("abcx"[3] == 'x', "...");
Judging by Compiler Explorer, there's clear consensus among tool vendors that doing this in the second context, which explicitly requires an integer constant expression, is not allowed. However, they seem to differ about the first context, which is only an arithmetic constant expression used in an initializer. GCC and Clang stand out as implementations which permit this.
By itself this isn't interesting because in paragraph 10 of 6.6, C11/C18 does say that "an implementation may accept other forms of constant expressions." However, it stands out in this case because:
GCC and Clang are both accepting this silently with
-pedantic
(true, signoff by a compiler doesn't mean code is conforming). Building the code makes sense as its meaning is straightforward, but I would expect a warning if they thought this wasn't conforming, and they can recognize whether (they think) it is or not, because...for both compilers, the behaviour has changed recently - Clang used to raise an error over this up until 3.8, while GCC used to raise an error up until 8.0. These versions came out in 2016 and 2018 respectively. This suggests the change was intentional, but I haven't yet found release notes for either compiler that go into this level of detail.
The timing of the change in behaviour makes it look like this was something to do with C18, but the wording of 6.6 doesn't seem to have changed. The restrictions on integer constant expressions remain strict (as shown by the second line continuing to error), and the wording of paragraph 9 seems the same as it was in C11, in particular continuing to say that "the value of an object shall not be accessed by use of these operators" (w.r.t []
and friends).
Is the first context a valid initializer constant by any reading of the standard, not counting paragraph 10? Is there anywhere I would be likely to find a rationale for the GCC/Clang changes?