Wie functionieren designated initializers?

Gast #4522194
Hallo,

kann mir jemand sagen wie das da unten funktioniert bzw. was das genau 
ist und wozu man es benutzen kann? Was ein struct ist, ist mir klar aber 
bei mir sehen die irgendwie einfacher aus.
1
static const struct pios_overo_cfg pios_overo_cfg = {
2
    .regs  = SPI2,
3
    .remap = GPIO_AF_SPI2,
4
    .init  = {
5
        .SPI_Mode              = SPI_Mode_Slave,
6
        .SPI_Direction         = SPI_Direction_2Lines_FullDuplex,
7
        .SPI_DataSize          = SPI_DataSize_8b,
8
        .SPI_NSS                                   = SPI_NSS_Hard,
9
        .SPI_FirstBit          = SPI_FirstBit_MSB,
10
        .SPI_CRCPolynomial     = 7,
11
        .SPI_CPOL              = SPI_CPOL_High,
12
        .SPI_CPHA              = SPI_CPHA_2Edge,
13
        .SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2,
14
    },
15
    .use_crc = false,
16
    .dma     = {
17
        .irq                                       = {
18
            // Note this is the stream ID that triggers interrupts (in this case TX)
19
            .flags = (DMA_IT_TCIF7),
20
            .init  = {
21
                .NVIC_IRQChannel    = DMA1_Stream7_IRQn,
22
                .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
23
                .NVIC_IRQChannelSubPriority        = 0,
24
                .NVIC_IRQChannelCmd = ENABLE,
25
            },
26
        },
27

28
        .rx                                        = {
29
            .channel = DMA1_Stream0,
30
            .init    = {
31
                .DMA_Channel            = DMA_Channel_0,
32
                .DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR),
33
                .DMA_DIR                = DMA_DIR_PeripheralToMemory,
34
                .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,
35
                .DMA_MemoryInc          = DMA_MemoryInc_Enable,
36
                .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
37
                .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,
38
                .DMA_Mode               = DMA_Mode_Circular,
39
                .DMA_Priority           = DMA_Priority_Medium,
40
                // TODO: Enable FIFO
41
                .DMA_FIFOMode           = DMA_FIFOMode_Disable,
42
                .DMA_FIFOThreshold      = DMA_FIFOThreshold_Full,
43
                .DMA_MemoryBurst        = DMA_MemoryBurst_Single,
44
                .DMA_PeripheralBurst    = DMA_PeripheralBurst_Single,
45
            },
46
        },
47
        .tx                                        = {
48
            .channel = DMA1_Stream7,
49
            .init    = {
50
                .DMA_Channel            = DMA_Channel_0,
51
                .DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR),
52
                .DMA_DIR                = DMA_DIR_MemoryToPeripheral,
53
                .DMA_PeripheralInc      = DMA_PeripheralInc_Disable,
54
                .DMA_MemoryInc          = DMA_MemoryInc_Enable,
55
                .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
56
                .DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte,
57
                .DMA_Mode               = DMA_Mode_Circular,
58
                .DMA_Priority           = DMA_Priority_Medium,
59
                .DMA_FIFOMode           = DMA_FIFOMode_Disable,
60
                .DMA_FIFOThreshold      = DMA_FIFOThreshold_Full,
61
                .DMA_MemoryBurst        = DMA_MemoryBurst_Single,
62
                .DMA_PeripheralBurst    = DMA_PeripheralBurst_Single,
63
            },
64
        },
65
    },
66
    .sclk                                          = {
67
        .gpio = GPIOB,
68
        .init = {
69
            .GPIO_Pin   = GPIO_Pin_13,
70
            .GPIO_Speed = GPIO_Speed_100MHz,
71
            .GPIO_Mode  = GPIO_Mode_AF,
72
            .GPIO_OType = GPIO_OType_PP,
73
            .GPIO_PuPd  = GPIO_PuPd_NOPULL
74
        },
75
    },
76
    .miso                                          = {
77
        .gpio = GPIOB,
78
        .init = {
79
            .GPIO_Pin   = GPIO_Pin_14,
80
            .GPIO_Speed = GPIO_Speed_50MHz,
81
            .GPIO_Mode  = GPIO_Mode_AF,
82
            .GPIO_OType = GPIO_OType_PP,
83
            .GPIO_PuPd  = GPIO_PuPd_NOPULL
84
        },
85
    },
86
    .mosi                                          = {
87
        .gpio = GPIOB,
88
        .init = {
89
            .GPIO_Pin   = GPIO_Pin_15,
90
            .GPIO_Speed = GPIO_Speed_50MHz,
91
            .GPIO_Mode  = GPIO_Mode_AF,
92
            .GPIO_OType = GPIO_OType_PP,
93
            .GPIO_PuPd  = GPIO_PuPd_NOPULL
94
        },
95
    },
96
    .slave_count                                   = 1,
97
    .ssel                                          = {
98
        {
99
            .gpio = GPIOB,
100
            .init = {
101
                .GPIO_Pin   = GPIO_Pin_12,
102
                .GPIO_Speed = GPIO_Speed_50MHz,
103
                .GPIO_Mode  = GPIO_Mode_OUT,
104
                .GPIO_OType = GPIO_OType_PP,
105
                .GPIO_PuPd  = GPIO_PuPd_UP
106
            },
107
        }
108
    },
109
};
#4522214
Das sind einfach mehrfach verschachtelte Strukturen.

Die selbe Initialisierung würde als Code so aussehen:
1
pios_overo_cfg.regs  = SPI2;
2
pios_overo_cfg.remap = GPIO_AF_SPI2;
3
pios_overo_cfg.init.SPI_Mode              = SPI_Mode_Slave;
4
pios_overo_cfg.init.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
5
pios_overo_cfg.init.SPI_DataSize          = SPI_DataSize_8b;
6
//...
7
pios_overo_cfg.use_crc = false;
8
// Note this is the stream ID that triggers interrupts (in this case TX)
9
pios_overo_cfg.dma.irq.flags = (DMA_IT_TCIF7);
10
pios_overo_cfg.dma.irq.init.NVIC_IRQChannel    = DMA1_Stream7_IRQn;
11
pios_overo_cfg.dma.irq.init.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH;
12
pios_overo_cfg.dma.irq.init.NVIC_IRQChannelSubPriority        = 0;
13
pios_overo_cfg.dma.irq.init.NVIC_IRQChannelCmd = ENABLE;
14
pios_overo_cfg.dma.rx.channel = DMA1_Stream0;
15
pios_overo_cfg.dma.rx.init.DMA_Channel            = DMA_Channel_0;
16
pios_overo_cfg.dma.rx.init.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR);
17
//...
Persönliche Seite #4522436
Vereinfacht:
1
struct bla
2
{
3
  int a;
4
  int b;
5
  int c;
6
};
7

8
// klassische Initialisierung
9

10
struct bla eins = { 1, 2, 3 };
11

12
// mit "designated initializers"
13

14
struct bla zwei = { .b = 2, .a = 1, .c = 3 };

Bei der klassischen Initialisierung müssen die Initialisierer in der 
korrekten Reihenfolge angegeben werden, wenn nur ein Element der 
Struktur (mit einem von 0 abweichenden Wert) initialisiert werden soll, 
dann müssen alle Elemente der Struktur, die in der Deklaration vorher 
stehen, auch initialisiert werden.

Will man im obigen Beispiel nur das Strukturelement c initialisieren, 
müssen der Reihenfolge wegen zwangsweise auch a und b initialisiert 
werden.

Bei "designated initializers" ist die Reihenfolge egal, und so ist auch 
eine alleinige Initialisierung von c möglich; a und b werden dann mit 0 
initialisiert.
Gast #4522590
Und gerade bei einer so komplexen Struktur hat man den Vorteil, dass man 
gleich sieht, welches Element welchen Wert bekommt, ohne dass man 
daneben noch die Definition des Typs sehen und die Elemente einzeln 
abzählen muss.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.