pointer auf typedef array

OP #5304153
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!
Gast #5304235
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.
Persönliche Seite #5304279
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?
#5304296
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.
#5304486
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.

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