Forum: Compiler & IDEs Wie functionieren designated initializers?


von Christian J. (Gast)


Lesenswert?

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

von Clemens L. (c_l)


Lesenswert?

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
//...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Christian J. (Gast)


Lesenswert?

Aha .... na, bisher bin ich irgendwie auch ohne das ausgekommen. 
Vermutlich weil ich so gut wie nie initialisierte Variablen brauche.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.