Связанный массив должен быть интегральным константным выражением, см. 8.3.4 [dcl.array]/1 (та же формулировка в C++03 и C++11):
Если константное выражение (5.19) присутствует, оно должно быть интегральным постоянным выражением, и его значение должно быть больше нуля.
В C++03 целочисленное константное выражение не может быть инициализировано литералом с плавающей запятой, если только оно не приведено к целочисленному типу, см. последнее предложение в 5.19 [expr.const]/1:
Интегральное выражение-константа может включать только литералы (2.13), перечислители, const переменные или статические элементы данных целочисленного или перечисляемого типов, инициализированные константными выражениями (8.5), параметры нетипового шаблона интегрального или перечисляемого типы и sizeof выражения. Плавающие литералы (2.13.3) могут появляться только в том случае, если они приведены к целочисленному типу или типу перечисления.
Это означает, что в C++03 i не является целочисленным константным выражением, поэтому его нельзя использовать в качестве связанного массива.
GCC и Clang допускают массивы переменной длины в качестве расширения C++03, поэтому он компилируется с неконстантной привязкой, но вы получаете предупреждение с -pedantic. Изменение инициализатора константы для приведения ее к целочисленному типу делает i допустимым целочисленным константным выражением:
const int i = (int) 1.0;
С этим изменением массив больше не имеет переменной длины, и нет предупреждения даже с -pedantic.
В С++ 11 5.19 [expr.const]/3 говорится:
Литеральное константное выражение – это основное константное выражение prvalue литерального типа, но не типа указателя. Интегральное константное выражение – это буквальное константное выражение интегрального типа или перечисления с незаданной областью.
Предыдущие (довольно длинные) абзацы описывают правила для основных константных выражений, но в основном в C++11 двойной инициализатор не препятствует тому, чтобы i было основным константным выражением, даже без приведения, поэтому это целочисленное константное выражение и, следовательно, действительная привязка массива, поэтому никаких предупреждений.
person
Jonathan Wakely
schedule
07.06.2012
iдвойным, а не целым? - person David   schedule 07.06.2012const int i = 1;. Имеет ли это? - person jweyrich   schedule 07.06.2012-pedanticв clang++ 3.1 дает аналогичное предупреждение. Если вы измените его наconst int i = 1;, предупреждение исчезнет. - person Jesse Good   schedule 07.06.2012