Строковые литералы слегка волшебны.Обычно (при использовании в выражениях) они представляют собой массивы.Массивы могут "распадаться" (неявно преобразовываться) в указатели, поэтому, например, допустимо
const char *p = "foo";
."foo"
здесь нормальное выражение.Вы также можете написать
const char *p;
p = "foo"; // assignment, not initialization
Однако, если строковый литерал используется для инициализации массива, он ведет себя как список символов инициализатора:
char s[] = "foo";
// equivalent to:
char s[] = { 'f', 'o', 'o', '\0' };
В вашем примере
const char d[] = ( *p ? "amet" : "consectetur" );
инициализатор не является строковым литералом;это выражение.Следовательно, оба строковых литерала распадаются на указатели, и тогда вы получаете ошибку, потому что вы не можете инициализировать массив из указателя.(На самом деле, вы вообще не можете инициализировать массив из выражения.)