Forum: Mikrocontroller und Digitale Elektronik Konstanter Zeiger auf ein Array der Größe 2 eines volatile structs


von Walter T. (nicolas)


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

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Wenn &arr schon keine Warnung bringt, sind Warnungen wohl aus.

Was ist sizeof(Mystruct_t)?

Und wofür die Klammern und *const arrp?

von Walter T. (nicolas)


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.

: Bearbeitet durch User
von EAF (Gast)


Lesenswert?

Walter T. schrieb:
> Ich hätte hier wirklich gerne Indexschreibweise.
Und?
Was hindert dich?
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 *array = arr;
13
    array[0].a = 10;
14
    array[1].a = 20;
15
}

von Walter T. (nicolas)


Lesenswert?

Hng. Vielleicht sollte ich heute abend einfach nicht programmieren.

Danke!

von Nop (Gast)


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.

von Markus F. (mfro)


Lesenswert?

1
void foo(void)
2
{
3
   Mystruct_t volatile (*const arrp)[2] = &arr;
4
5
   (*arrp)[0].a = 10;
6
   (*arrp)[1].a = 20;
7
}

tät's auch

: Bearbeitet durch User
von ein lupenreiner Demokrat (Gast)


Lesenswert?

Nö, er hat ja

Walter T. schrieb:
> volatile Mystruct_t arr[2];
>

und nicht
1
Mystruct_t arr[42][2];

Ein mal ein Array von int-Werten und ein mal ein Array von 
zweidimensionalen int-Arrays.

von Sebastian (Gast)


Lesenswert?

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

Nein. Oder hast du mehrere solcher Arrays?

LG, Sebastian

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.