Инициализатор строк с фигурными фигурными скобками

Я наткнулся на часть кода, выполнив следующую инициализацию:

static const uint8_t s[] = {"Some string"};

Я бы предположил, что он будет интерпретироваться следующим образом: правая сторона сопоставляет массив указателей char с одним элементом, который указывает на строковый литерал "Some string". Левая часть представляет собой массив uint8_t. Тогда я бы ожидал, что первый элемент s получит некоторое укороченное значение указателя на строковый литерал, что приведет к неожиданному поведению в следующем коде, предполагая, что s является строкой.

Я сделал следующий тестовый код:

#include <stdint.h>
#include <stdio.h>

static const uint8_t s1[] = "String1";
static const uint8_t s2[] = { "String2" };
int main(void){

    printf("%p, %p\n", s1, s2);
    printf("%s, %s\n", s1, s2);

    return 0;
}

К моему удивлению, похоже, что этого не происходит. Не только код будет работать правильно, но и дизассемблирование показывает, что оба s1 и s2 инициализируются как соответствующие строки одинаковым образом.

Является ли это чем-то gcc конкретным? Является ли синтаксис синтаксиса синтаксисом единственного строкового литерала в {} и все еще интерпретирует его как строковый литерал?

Ответ 1

Цитата из N1570 (окончательный вариант C11), 6.7.9 Инициализация (выделение):

  1. Массив типа символа может быть инициализирован символьной строкой литеральный или UTF-8 строковый литерал, , необязательно заключенный в фигурные скобки. Последовательные байты строкового литерала (включая завершающий нуль символ, если есть место или массив неизвестного размера) инициализировать элементы массива.

Ответ 2

Ответ на qingyao на солнце правильно указывает, что вы можете добавить дополнительные фигурные скобки для такого инициализатора. Стоит упомянуть, что это относится не только к массивам:

int x = { 0 };

компилирует, даже если инициализированный элемент не является массивом. Это объясняется следующим предложением:

6.7.9.11 Инициализатором для скаляра должно быть одно выражение, необязательно заключенное в фигурные скобки.

Но зачем это разрешено? Ответ заключается в том, что это позволяет инициализировать значения одним синтаксисом:

T x = { 0 };

работает для любого T и нуль инициализирует все (для structs, each member, для массивов, для каждого элемента, для скалярных типов, просто инициализирует значение).