Forum: Mikrocontroller und Digitale Elektronik pointer auf typedef array


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich versuche meiner Funktion ein struct array zu übergeben.

Leider mache ich wohl irgendwas falsch:
1
typedef struct {
2
  jsmntype_t type;
3
  int start;
4
  int end;
5
  int size;
6
} jsmntok_t;
7
8
...
9
10
meineFunktion(jsmntok_t *tokens[])
11
{
12
  tokens[0]->....;
13
}
14
15
16
....
17
18
jsmntok_t tokens[1024];
19
20
meineFunktion(&tokens[0]);

Leider bekomme ich immer die Meldung:
1
expected 'jsmntok_t ** {aka struct <anonymous> **}' but argument is of type 'jsmntok_t (*)[1024] {aka struct <anonymous> (*)[1024]}'
2
3
..\foo.c:137:64: warning: passing argument 1 of 'meineFunktion' from incompatible pointer type [-Wincompatible-pointer-types]

Weiss jemand Rat?
Danke!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Holger K. schrieb:

meineFunktion(jsmntok_t *tokens)

oder

meineFunktion(jsmntok_t tokens[])

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Holger K. schrieb:

...und der Zugriff dann:

tokens[0].....;

zähl deine Punkte :-P

von Holger K. (holgerkraehe)


Lesenswert?

Johann L. schrieb:
> meineFunktion(jsmntok_t *tokens)

Dann kommt:
1
invalid type argument of '->' (have 'jsmntok_t {aka struct <anonymous>}')

Bei
1
tokens[0]->....;

Johann L. schrieb:
> meineFunktion(jsmntok_t tokens[])

Würde wohl funktioniere, aber hier würde ja der Inhalt kopiert werden.
Dies möchte ich ja eben nicht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Holger K. schrieb:
> Johann L. schrieb:
>> meineFunktion(jsmntok_t tokens[])
>
> Würde wohl funktioniere, aber hier würde ja der Inhalt kopiert werden.
> Dies möchte ich ja eben nicht.

Das wird er auch nicht. tokens[] ist an dieser Stelle absolut identisch 
zu *tokens.

von Nop (Gast)


Lesenswert?

Holger K. schrieb:
> meineFunktion(&tokens[0]);

Die mußt Du dann natürlich auch so aufrufen:
meineFunktion(tokens);

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nop schrieb:
> Die mußt Du dann natürlich auch so aufrufen:
> meineFunktion(tokens);

Muss nicht aber kann.

von Nop (Gast)


Lesenswert?

Johann L. schrieb:

> Muss nicht aber kann.

Sollte, weil zwar die übergebene Adresse in beiden Fällen dieselbe ist, 
aber nicht der assoziierte Typ.

von Carl D. (jcw2)


Lesenswert?

Nop schrieb:
> Johann L. schrieb:
>
>> Muss nicht aber kann.
>
> Sollte, weil zwar die übergebene Adresse in beiden Fällen dieselbe ist,
> aber nicht der assoziierte Typ.

Das macht in reinem C keinen Unterschied.
Außer natürlich für den Code-Leser.

von Nop (Gast)


Lesenswert?

Carl D. schrieb:

> Das macht in reinem C keinen Unterschied.

Wenn wie hier, bei der Übergabe an eine Funktion nicht, weil C dann eh 
castet. Beim Benutzen von sizeof schon.

> Außer natürlich für den Code-Leser.

Und damit auch für Code-Analysetools, die einen vor Typfehlern warnen 
sollen. Mich würd's nicht wundern, wenn je nach Warnstufe sogar der eine 
oder andere Compiler meckern würde.

von Carl D. (jcw2)


Lesenswert?

Nop schrieb:
> Carl D. schrieb:
>
>> Das macht in reinem C keinen Unterschied.
>
> Wenn wie hier, bei der Übergabe an eine Funktion nicht, weil C dann eh
> castet. Beim Benutzen von sizeof schon.

Deshalb hat der Holger auch einen eigenen Thread zum Thema sizeof.
Weil's darum hier nicht geht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nop schrieb:
> Johann L. schrieb:
>
>> Muss nicht aber kann.
>
> Sollte, weil zwar die übergebene Adresse in beiden Fällen dieselbe ist,
> aber nicht der assoziierte Typ.

Wenn ich mit gcc folgendes übersetze
1
typedef struct { char a[3]; } __attribute((packed)) S;
2
3
S g[7];
4
5
#define T(x,y) _Generic((x), __typeof(y):1, default:0)
6
7
int main()
8
{
9
    static char volatile v;
10
    v = T (g, g);
11
    v = T (g, &g[0]);
12
    __typeof(g) b;
13
    v = sizeof (g);
14
    v = sizeof (b);
15
}
dann werden nacheinander folgende Werte in v gespeichert: 0, 1, 21, 21.

Die beiden letzten Werte sind klar, aber warum hat g nicht den Typ von g 
sondern den von &g[0]?

Verwirrt ich bin.  Oder ist das ein Bug?

von Carl D. (jcw2)


Lesenswert?

Johann L. schrieb:
> Nop schrieb:
>> Johann L. schrieb:
>>
>>> Muss nicht aber kann.
.
>> Sollte, weil zwar die übergebene Adresse in beiden Fällen dieselbe ist,
>> aber nicht der assoziierte Typ.
.
> Wenn ich mit gcc folgendes übersetzetypedef struct { char a[3]; }
> __attribute((packed)) S;
>
> S g[7];
>
> #define T(x,y) _Generic((x), __typeof(y):1, default:0)
>
> int main()
> {
>     static char volatile v;
>     v = T (g, g);
>     v = T (g, &g[0]);
>     __typeof(g) b;
>     v = sizeof (g);
>     v = sizeof (b);
> }
> dann werden nacheinander folgende Werte in v gespeichert: 0, 1, 21, 21.
>
> Die beiden letzten Werte sind klar, aber warum hat g nicht den Typ von g
> sondern den von &g[0]?
>
> Verwirrt ich bin.  Oder ist das ein Bug?

Wenn (x) als Parameter der "Funktion" _Generic() angesehen wird, 
__typeof() aber den "echten" Typ ermittelt, dann würde es passen.
Wenn auch etwas strange.

von Rolf M. (rmagnus)


Lesenswert?

Nop schrieb:
> Mich würd's nicht wundern, wenn je nach Warnstufe sogar der eine
> oder andere Compiler meckern würde.

Ich hoffe nicht, denn der implizite "Zerfall" von Arrays in einen Zeiger 
auf deren erstes Element ist ein ziemlich grundlegendes Konzept in C, 
das fast überall vorkommt, wo Arrays eingesetzt werden.

Johann L. schrieb:
> Die beiden letzten Werte sind klar, aber warum hat g nicht den Typ von g
> sondern den von &g[0]?

Weil auf das erste g der Array-zu-Zeiger-Zerfall auch angewendet wird, 
auf das zweite aber nicht.
Aus http://en.cppreference.com/w/c/language/generic :

The conversion is performed in type domain only: it discards the 
top-level cvr-qualifiers and atomicity or applies array to 
pointer/function-to-pointer transformations to the type of the 
controlling expression, without initiating any side-effects or 
calculating any values.
Therefore, "abc" matches char* and not char[4] and (int const){0} 
matches int, and not const int.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Rolf M. schrieb:

> Ich hoffe nicht, denn der implizite "Zerfall" von Arrays in einen Zeiger

Hast natürlich recht, weil &array[0] dann auch genau den richtigen 
Zeigertyp hat für die Funktion.

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.