Konstanter Zeiger auf ein Array der Größe 2 eines volatile structs

OP #7260671
Lesenswert?

Guten Abend,

mir gehen gerade Zeiger wieder auf den ... Nerv.
1
typedef struct
2
{
3
    int a;
4
    int b;
5
}
6
Mystruct_t;
7

8
volatile Mystruct_t arr[2];
9

10
void foo(void)
11
{
12
    Mystruct_t volatile (*const arrp)[2] = &arr;
13

14
    arrp[0]->a = 10;
15
    arrp[1]->a = 20;
16
}
Was ich vor habe, kann man sich ja denken, wenn man nicht gerade ein 
Compiler ist. Ich verstehe aber gerade (mal wieder) nicht, wie der 
Compiler das sieht. Der macht nämlich bei der zweiten Zuweisung einen 
Offset von 16 anstelle der erwarteten 8 Bytes:
1
(78)  {
2
(79)      Mystruct_t volatile (*const arrp)[2] = &arr;
3
(80)  
4
(81)      arrp[0]->a = 10;
5
08002D6C  ldr  r3, [pc, #8]  ; (0x8002d78 <foo+12>)
6
08002D6E  movs  r2, #10
7
08002D70  str  r2, [r3, #0]
8
(82)      arrp[1]->a = 20;
9
08002D72  movs  r2, #20
10
08002D74  str  r2, [r3, #16]
11
08002D76  bx  lr
12
08002D78  asrs  r0, r2, #4
13
08002D7A  movs  r0, #0
Natürlich kein Fehler, keine Warnung, keine Badbox.

arr[] ist ein volatiles Array mit zwei Elementen aus structs vom Typ 
Mystruct_t.

arrp sollte ein konstanter Zeiger auf ein volatiles Array mit zwei 
Elementen vom Typ Mystruct_t sein.

Wo liegt mein Denkfehler?

(Das hier geht natürlich:
1
    Mystruct_t volatile *const arrp = &arr[0];
2

3
    (*(arrp+1)).a = 20;
aber die Frage ist ja, was oben schief läuft.)
OP #7260706
Lesenswert?

A. S. schrieb:
> Was ist sizeof(Mystruct_t)?

8, wie erwartet.

A. S. schrieb:
> Wenn &arr schon keine Warnung bringt, sind Warnungen wohl aus.

Hm, stimmt, ich referenziere eine Ebene zu tief. Da muss ich nochmal von 
vorn knobeln. Ich hätte hier wirklich gerne Indexschreibweise.

A. S. schrieb:
> Und wofür die Klammern und *const arrp?

Beim Optimierungs-Level 1 wird der Zugriff auf die Speicherstelle nicht 
wegoptimiert, wenn ich den Zeiger nicht konstant mache.
Gast #7260741
Lesenswert?

Walter T. schrieb:

> arrp sollte ein konstanter Zeiger auf ein volatiles Array mit zwei
> Elementen vom Typ Mystruct_t sein.

Na eben. Wenn Du einen Pointer raufzählst (wie in arrp[1]), wird die 
Datenbreite seines zugrundeliegenden Typen in Bytes addiert. Der 
zugrundeliegende Typ ist ein volatiles Array mit zwei Elementen vom Typ 
Mystruct_t (je 8 Bytes), also 16 Bytes.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren