2016-04-05 11 views
10

ho incontrato un pezzo di codice esegue la seguente inizializzazione:String inizializzatore con graffe

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

mi si aspetterebbe che sia interpretato come segue: Il lato destro sta abbinando un array di puntatori char con singolo elemento che punta a una stringa letterale "Some string". Mentre la parte sinistra è un array di uint8_t. Quindi il comportamento che mi aspetto è che il primo elemento di s riceva qualche valore troncato del puntatore al letterale stringa, causando in tal modo un comportamento imprevisto nel seguente codice, supponendo che s sia una stringa.

Ho fatto il seguente codice di prova:

#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; 
} 

Per la mia sorpresa sembra che non sta accadendo. Non solo il codice funzionerà correttamente, ma anche lo smontaggio mostra che sia s1 sia s2 vengono inizializzati come stringhe corrispondenti in modo identico.

È qualcosa di specifico gcc? La sintassi C consente di prendere letteralmente la stringa singola in {} e interpretarla ancora come stringa letterale?

+0

Aggiungere una seconda stringa e vedere cosa succede: 'static const uint8_t s2 [] = {" String2 "," String3 "};' – LPs

+0

@LPs Sì, l'ho provato. –

+0

Ok, DevSolar ti ha dato quello che ti serve. – LPs

risposta

16

Citato da N1570 (progetto finale di C11), 6.7.9 Inizializzazione (enfasi mia):

  1. Matrice di tipo carattere può essere inizializzato da un carattere stringa letterale stringa letterale o UTF-8, facoltativamente incluso tra parentesi graffe. Byte successivi della stringa letterale (incluso il carattere nullo nullo se c'è spazio o se la matrice è di dimensioni sconosciute) inizializza gli elementi dell'array.
+2

Ok, questo sta rispondendo esplicitamente alla domanda. Grazie. –

8

La risposta del Qingyao sole cita correttamente che è possibile aggiungere le parentesi extra per tale initializer. Vale la pena di citare questo non si applica solo alle matrici:

int x = { 0 }; 

compiles anche se l'elemento in fase di inizializzazione non è un array. Questo grazie alla seguente clausola:

6.7.9.11 L'inizializzatore di uno scalare è una singola espressione, eventualmente racchiusa tra parentesi.

Ma perché sarebbe permesso? La risposta è, ciò rende possibile inizializzare i valori con un singolo sintassi:

T x = { 0 }; 

opere per qualsiasi T e zero inizializza tutto (per le strutture, ogni membro, per gli array, ogni elemento, per i tipi scalari, appena inizializza il valore).

+1

È possibile aggiungere un riferimento: '11 L'inizializzatore per uno scalare deve essere una singola espressione, facoltativamente racchiuso tra parentesi graffe. –

+0

@sun qingyao Penso che solo quel riferimento sarebbe qualificato come risposta completa. Sebbene tecnicamente l'entità inizializzata non sia uno scalare .... –