C: Struct function pointer prototype

OP #5923433
Lesenswert?

Guten Morgen,

ich habe in einem struct einen Funktionszeiger auf eine Funktion, die 
den struct als Parameter übergeben bekommt:
1
typedef struct IconData_s
2
{
3
    void (*fcn) (IconData_t);
4
    uint8_t slot;
5
    int8_t thisState;
6
    int8_t lastState;
7
}
8
IconData_t;
Das funktioniert. Die Funktion läßt sich beim Iterieren über das struct 
array aufrufen.

Will ich stattedessen eine Funktion mit Funktionszeiger als Argument 
aufrufen, schlägt der Build fehl:
1
typedef struct IconData_s
2
{
3
    void (*fcn) (IconData_t *);
4
    uint8_t slot;
5
    int8_t thisState;
6
    int8_t lastState;
7
}
8
IconData_t;
Stattdessen muß ich mit einem "incomplete type struct" hantieren:
1
struct IconData_s;
2
typedef struct IconData_s IconData_t;
3

4
struct IconData_s
5
{
6
    void (*fcn) (IconData_t *);
7
    uint8_t slot;
8
    int8_t thisState;
9
    int8_t lastState;
10
};


Was ist für den Compiler (hier: ARM-GCC) der große Unterschied?
Gast #5923448
Lesenswert?

Walter T. schrieb:
> Guten Morgen,
>
> ich habe in einem struct einen Funktionszeiger auf eine Funktion, die
> den struct als Parameter übergeben bekommt:typedef struct IconData_s
> {
>     void (*fcn) (IconData_t);
>     uint8_t slot;
>     int8_t thisState;
>     int8_t lastState;
> }
> IconData_t;
> Das funktioniert. Die Funktion läßt sich beim Iterieren über das struct
> array aufrufen.

Bist du sicher, dass das funktioniert? Würde mich wundern.
IcondData_t ist in dieser Zeile noch nicht bekannt.
1
void (*fcn) (IconData_t);
Wenn du die Warnungen einschaltest, sagt dir dein Compiler das auch.
1
warning: parameter names (without types) in function declaration
2
    3 |     void (*fcn) (IconData_t);
3
      |     ^~~~
Der Wortlaut der Warnung ist in diesem Fall nicht ideal, aber sollte 
einen in die richtige Richtung weisen.
OP #5923464
Lesenswert?

Die Warnung habe ich auch.

Es funktioniert insoweit, als daß das richtige passiert, d.h. die 
Funktion läßt sich korrekt aufrufen und schreibt auch einen Zahlenwert 
aus dem struct korrekt in die Konsole. Aber klar. Die Warnung ist da.

Nur das eine ist ein Fehler - das andere eine Warnung - was ist für den 
Kompiler der große Unterschied?
Beitrag #5923472 wurde von einem Moderator gelöscht.
Moderator #5923487
Lesenswert?

Dieses

1
    void (*fcn) (IconData_t);

ist K&R-C und steht für

1
    void (*fcn) (int IconData_t);

in ISO-C. IconData_t ist also nicht der Argumenttyp, sondern der
Argumentname.

Deswegen erscheint die Warnung

1
warning: parameter names (without types) in function declaration

(Name ist da, aber Typ fehlt)
Moderator #5923515
Lesenswert?

Clang liefert hier sogar einen Error:

1
test.c:5:18: error: a parameter list without types is only allowed in a
2
      function definition
3
    void (*fcn) (IconData_t);
4
                 ^

Ich habe auf die Schnelle zwar nicht die entsprechende Stelle in der
ISO-Norm gefunden, aber das die Fehlermeldung ist vermutlich
gerechtfertigt, da in K&R-C reine Deklarationen keine Argumentliste
enthalten.

Hier zeigt sich ein weiteres Mal die Problematik von typedef, die darin
besteht, dass syntaktisch nicht zwischen Typ- und Variablennamen
unterschieden werden kann. Im konkreten Fall wird ein Identifier, der
eigentlich als Typname gedacht ist, aber noch nicht deklariert wurde,
als Variablenname interpretiert.

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