Nenhum erro de compilador quando a matriz de caracteres de tamanho fixo é inicializada sem espaço suficiente para o terminador nulo

Suponha que eu tenha as seguintes matrizes de char c:

char okaysize4[5] = "four"; // line 5 char toosmall4[4] = "four"; // line 6 char toosmall3[3] = "four"; // line 7 

Quando eu compilo com o gcc 4.4.7, recebo o seguinte erro:

array.c: 7: aviso: initializer-string para array de chars é muito longo

Este erro é esperado para a linha 7, já que estou tentando colocar 5 caracteres ("four" + \0) em uma matriz de 3 elementos. Além disso, nenhum erro é esperado para a linha 5, pois a matriz de 5 elementos é grande o suficiente.

No entanto, estou surpreso que não haja erro semelhante para a linha 6. O que acaba sendo inicializado em toosmall4 é uma string não terminada, que pode causar todo tipo de problema.

Meu entendimento é que o literal da cadeia c "four" deve ter cinco caracteres, devido ao terminador nulo. Na verdade sizeof("four") é 5. Então, por que o compilador não dá um erro aqui?

Existe alguma maneira que eu possa alterar minha declaração / definição / boot para que um erro seja sinalizado nesse caso?

Este é o comportamento esperado para a linha 6, a partir do rascunho da seção padrão C99 . 6.7.8 parágrafo de boot 14 diz ( grifo meu ):

Uma matriz de tipo de caractere pode ser inicializada por um literal de cadeia de caracteres, opcionalmente entre chaves. Caracteres sucessivos do literal da cadeia de caracteres ( incluindo o caractere nulo de terminação, se houver espaço ou se o array for de tamanho desconhecido ) inicializam os elementos do array.

No esboço preliminar C11, a seção relevante com formulação similar é 6.7.9 parágrafo 14 , e como o C FAQ diz :

A matriz, portanto, não é uma string C verdadeira e não pode ser usada com o strcpy, o formato% s da printf, etc.

Como Keith Thompson observou, o C ++ é mais rigoroso, a seção relevante no rascunho do padrão C ++ diz o seguinte:

Não haverá mais inicializadores do que elementos de array. [Exemplo:

 char cv[4] = "asdf"; // error 

é mal formado, pois não há espaço para o rastreio implícito ‘\ 0’. – por exemplo

É legal, toosmall4 não é uma string, mas uma matriz char válida (sem o caractere nulo de terminação).

Referência: C FAQ .