C ++ 11, 6.4 / 4:
Значением условия, являющегося выражением, является значение выражения, контекстно преобразованное в bool для операторов, отличных от switch;если это преобразование некорректно, программа некорректно сформирована.
Таким образом, стандарт говорит, что компилятор должен выполнить любые неявные преобразования, имеющиеся в его распоряжении, чтобы преобразовать массив в логическое значение.Распад массива на указатель и преобразование указателя в логическое значение с проверкой на равенство нулю является одним из способов сделать это, так что да, программа хорошо определена, и да, она действительно дает правильный результат - очевидно, так как массивразмещенный в стеке указатель, на который он распадается, никогда не может быть равен нулевому указателю.
Обновление: Что касается , почему следует эта цепочка из двух преобразований:
C ++ 11, 4.2 / 1:
Значение l или значение типа «массив NT» или «массив неизвестной границы T» можно преобразовать в значение типа prvalue.типа «указатель на T».Результатом является указатель на первый элемент массива.
Таким образом, единственное допустимое преобразование из типа массива - это указатель на тип элемента.На первом шаге выбора нет.
C ++ 11, 4.12 / 1:
Значение арифметического перечисления с незаданной областью, указатель , указатель илиуказатель на тип члена может быть преобразован в значение типа bool
.Нулевое значение, значение нулевого указателя или значение указателя нулевого элемента преобразуется в false
;любое другое значение преобразуется в true
.Значение типа std::nullptr_t
может быть преобразовано в значение типа bool
;результирующее значение равно false
.
. Имеется неявное преобразование непосредственно из пустого указателя в логическое значение;поэтому компилятор выбирает это как второй шаг, потому что он позволяет немедленно достичь желаемого результата (преобразование в логическое значение).