2015-07-23 17 views
22

Während Lesen eines Artikels, stieß ich auf die folgende Funktion:Odd Syntax in C++: return {.name = value, ...}

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

Was ist der Autor mit der Aussage Rückkehr tun? So etwas habe ich noch nicht gesehen, und ich weiß nicht, wie ich danach suchen soll ... Gilt es auch für reines C?

Edit: link to the original article

+5

Gültig in C, Nicht-Standard-Erweiterung einiger Compiler für C++ (ab C++ 11 ist diese Funktionalität nicht im C++ - Standard.) –

+2

Siehe [der C-Standard] (http: //www.open- std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), Abschnitt _6.5.2.5 Zusammengesetzte Literale_, Punkt 10 (bezüglich designierter Initialisierer). – Michael

+1

Ich bin mir ziemlich sicher, dass das für Plain C gültig ist und _not_ für C++ gültig ist. – davmac

Antwort

21

Dies ist nicht gültig C++.

Es ist (eine Art) mit ein paar Features von C bekannt als "Compound-Literale" und "designed Initializers", die einige C++ - Compiler als Erweiterung unterstützen. Die „Art“ von dieser Tatsache kommt, dass eine legitime C Verbindung wörtliche zu sein, sollte es Syntax hat, der wie ein Guss aussieht, so müßten Sie so etwas wie:

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

Unabhängig von der Differenz in der Syntax, aber es ist im Grunde eine temporäre Struktur mit Mitgliedern der Erstellung initialisiert, wie im Block angegeben, so ist dies entspricht in etwa:

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

der große Unterschied (wie man sieht) ist, dass bezeichnet initializers können Sie Elementnamen verwenden, um festzulegen, welcher Initialisierer zu welchem ​​Mitglied geht, und nicht nur von der Reihenfolge/Position abhängig ist.

+0

Nur 'zurück {0, 1, (_width-1) * 4, 1000};' in C++ 11 funktioniert, keine Notwendigkeit für "r". Dies bringt die C++ - Syntax näher an die C99-Syntax und macht die Verschmelzung der beiden zu der oben verwendeten Syntax. – Yakk

9

Es ist ein C99 compound literal. Diese Funktion ist spezifisch für C99, aber gcc und clang entscheiden sich dafür, sie auch in C++ zu implementieren (wie extension).

6,26 Compound Literale

ISO C99 unterstützt Verbindung Literale. Ein zusammengesetztes Literal sieht wie eine Umwandlung aus, die einen Initialisierer enthält. Ihr Wert ist ein Objekt vom Typ , das in der Besetzung angegeben ist und die Elemente enthält, die in dem Initialisierer angegeben sind; es ist ein Wert. Als Erweiterung unterstützt GCC Compound Literale im C90-Modus und in C++, obwohl die Semantik in C++ etwas anders ist als .

+1

Uhm, was? "... sieht aus wie ein Cast, der einen Initialisierer enthält." das passt die Frage? -1. – Barry

+0

Das ist _not_ zusammengesetzter initializer_! Das würde einen in Klammern gesetzten Typ vor dem Block erfordern. Und der ursprüngliche Code ist C++ even, der nicht als Initialisierer bezeichnet wurde. – Olaf

+0

Diese Antwort ist falsch. Es ist si Ähnlichkeit mit einem C99 zusammengesetzten Literal, aber es ist definitiv nicht eins. –