2015-07-23 10 views
22

Durante la lettura di un articolo, mi sono imbattuto nel seguente funzione:sintassi dispari in C++: ritorno {.name = valore, ...}

SolidColor::SolidColor(unsigned width, Pixel color) 
    : _width(width), 
    _color(color) {} 

__attribute__((section(".ramcode"))) 
Rasterizer::RasterInfo SolidColor::rasterize(unsigned, Pixel *target) { 
    *target = _color; 
    return { 
    .offset = 0, 
    .length = 1, 
    .stretch_cycles = (_width - 1) * 4, 
    .repeat_lines = 1000, 
    }; 
} 

Qual è l'autore facendo con l'istruzione return? Non ho mai visto nulla di simile prima, e non so come cercarlo ... È valido anche per C semplice?

Edit: link to the original article

+5

Valido in C, estensione non standard di alcuni compilatori per C++ (a partire da C++ 11, questa funzionalità non è nello standard C++.) –

+2

Vedere [lo standard C] (http: //www.open- std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), sezione _6.5.2.5 Caratteri letterali composti, punto 10 (relativi agli inizializzatori designati). – Michael

+1

Sono abbastanza sicuro che sia valido per C semplice e non valido per C++. – davmac

risposta

21

Questo non è valido C++.

Si tratta (in un certo senso) di un paio di funzioni di C note come "letterali composti" e "inizializzatori designati", che alcuni compilatori C++ supportano come estensione. Il "sorta di" deriva da questo fatto che per essere un composto C legittima letterale, dovrebbe avere la sintassi che assomiglia a un cast, in modo da sarebbe avere qualcosa di simile:

return (RasterInfo) { 
    .offset = 0, 
    .length = 1, 
    .stretch_cycles = (_width - 1) * 4, 
    .repeat_lines = 1000, 
    }; 

A prescindere dalla differenza nella sintassi, tuttavia, è fondamentalmente la creazione di una struttura temporanea con i membri inizializzati come specificato nel blocco, quindi questo è più o meno equivalente a:

// A possible definition of RasterInfo 
// (but the real one might have more members or different order). 
struct RasterInfo { 
    int offset; 
    int length; 
    int stretch_cycles; 
    int repeat_lines; 
}; 

RasterInfo rasterize(unsigned, Pixel *target) { 
    *target = color; 
    RasterInfo r { 0, 1, (_width-1)*4, 1000}; 
    return r; 
} 

la grande differenza (come potete vedere) è che inizializzatori designati consentono di utilizzare i nomi dei membri per specificare quale inizializzatore va a quale membro, piuttosto che dipendere esclusivamente dall'ordine/posizione.

+0

Just 'return {0, 1, (_width-1) * 4, 1000};' in C++ 11 funziona, non c'è bisogno di 'r'. Il che avvicina la sintassi C++ alla sintassi C99 e rende la fusione dei due la sintassi usata sopra. – Yakk

9

Si tratta di un C99 compound literal. Questa funzione è specifica per C99, ma gcc e clang scelgono di implementarlo anche in C++ (come extension).

6,26 letterali composti

ISO C99 supporta letterali composti. Un composto letterale sembra un cast contenente un inizializzatore. Il suo valore è un oggetto del tipo specificato nel cast, contenente gli elementi specificati nell'inizializzatore ; è un lvalue. Come estensione, GCC supporta i letterali composti in modalità C90 e in C++, sebbene la semantica sia in qualche modo diversa in C++.

+1

Uhm, che cosa? "... sembra un cast contenente un inizializzatore." Come funziona? -1. – Barry

+0

Questo è _not_ inizializzatore composto_! Ciò richiede un tipo parentetizzato prima del blocco e il codice originale è anche C++ che non ha inizializzatori designati – Olaf

+0

Questa risposta è errata. simile a un letterale composito C99 ma sicuramente non lo è. –