Разница в том, что строковые литералы являются собственными массивами. "test"
используется здесь не как инициализатор массива (особый случай, когда он будет эквивалентен { 't', 'e', 's', 't', '\0' }
), но так же, как любое другое значение.
Другими словами, когда вы используете строковый литерал "test"
в своем коде, компилятор автоматически создает что-то вроде
static const char __str_literal0[] = {'t', 'e', 's', 't', '\0'};
, а затем
const char *example = "test";
компилируется, как если бы это было
const char *example = __str_literal0;
т.е. он просто указывает на (уже существующий, статический) массив символов.
С другой стороны, если вы попытаетесь использовать список инициализаторов, компилятор установит первое поле вашей переменной (это просто example
) на первое значение в списке инициализаторов (example = 0x74
), и затем пожаловайтесь, что в вашем списке слишком много инициализаторов.