Je pensais ne pas trop être mauvais en C, mais me voilà confronté à un
élément de la norme C99 apparemment... En compilant un programme avec
GCC 3.3.1, j'obtiens l'avertissement suivant (qui conduit à l'arrêt de
la compilation) :
warning: dereferencing type-punned pointer will break strict-aliasing rules
Je pourrais bien sûr utiliser l'option de compilation
no-strict-aliasing, mais je suppose qu'il vaudrait mieux régler le
problème proprement.
J'ai trouvé quelques infos intéressantes en cherchant sur Google, par
exemple ce message qui m'a permis de comprendre (à peu près) le pb :
La solution utilisée dans beaucoup de projets libres est apparemment
d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très
propre, même si c'était autorisé...
Questions :
Quel est la traduction correcte de "type punning" ?
Est-ce que l'utilisation de cette technique révèle une erreur de
conception du programme ?
Pour info le programme en question est gnome-build, et l'erreur est la
suivante :
La solution utilisée dans beaucoup de projets libres est apparemment d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très propre, même si c'était autorisé...
C'est propre et c'est correct.
Questions :
Quel est la traduction correcte de "type punning" ?
"Transtypage à la barbare"
Est-ce que l'utilisation de cette technique révèle une erreur de conception du programme ?
Moui, souvent...
Pour info le programme en question est gnome-build, et l'erreur est la suivante :
... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est vrai que je n'aime pas trop ça... est-tu sûr que le cast est nécessaire? Un cast a surtout l'inconvéniant de faire sauter les contrôles de types. Il dit au compilateur : "Moi, programmeur, je sais ce que je fais, me casse pas les pieds avec tes warnings..." Est-ce toujours le cas? Comment le valider ?
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
In 'fr.comp.lang.c', Nicolas PENINGUY <np.news@free.fr> wrote:
warning: dereferencing type-punned pointer will break strict-aliasing rules
Je pourrais bien sûr utiliser l'option de compilation
no-strict-aliasing, mais je suppose qu'il vaudrait mieux régler le
problème proprement.
A priori, oui, mais quelques fois, on ne peut pas faire autrement...
J'ai trouvé quelques infos intéressantes en cherchant sur Google, par
exemple ce message qui m'a permis de comprendre (à peu près) le pb :
La solution utilisée dans beaucoup de projets libres est apparemment
d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très
propre, même si c'était autorisé...
C'est propre et c'est correct.
Questions :
Quel est la traduction correcte de "type punning" ?
"Transtypage à la barbare"
Est-ce que l'utilisation de cette technique révèle une erreur de
conception du programme ?
Moui, souvent...
Pour info le programme en question est gnome-build, et l'erreur est la
suivante :
... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est vrai que je n'aime pas trop ça... est-tu sûr que le cast est
nécessaire? Un cast a surtout l'inconvéniant de faire sauter les contrôles de
types. Il dit au compilateur : "Moi, programmeur, je sais ce que je fais, me
casse pas les pieds avec tes warnings..." Est-ce toujours le cas? Comment le
valider ?
--
-ed- emdelYOURBRA@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
La solution utilisée dans beaucoup de projets libres est apparemment d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très propre, même si c'était autorisé...
C'est propre et c'est correct.
Questions :
Quel est la traduction correcte de "type punning" ?
"Transtypage à la barbare"
Est-ce que l'utilisation de cette technique révèle une erreur de conception du programme ?
Moui, souvent...
Pour info le programme en question est gnome-build, et l'erreur est la suivante :
... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est vrai que je n'aime pas trop ça... est-tu sûr que le cast est nécessaire? Un cast a surtout l'inconvéniant de faire sauter les contrôles de types. Il dit au compilateur : "Moi, programmeur, je sais ce que je fais, me casse pas les pieds avec tes warnings..." Est-ce toujours le cas? Comment le valider ?
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Quel est la traduction correcte de "type punning" ?
"Transtypage à la barbare"
Ok ! :)
C'est vrai que je n'aime pas trop ça... est-tu sûr que le cast est nécessaire?
À vrai dire le programme n'est pas de moi, juste envie d'y contribuer/d'apprendre. Je vais essayer de regarder un peu plus en profondeur la chose...
Merci pour la réponse, c'est plus sympa que sur clcm ici ! :)
Gabriel Dos Reis
Nicolas PENINGUY writes:
| Salut, | | Je pensais ne pas trop être mauvais en C, mais me voilà confronté à un | élément de la norme C99 apparemment... En compilant un programme avec | GCC 3.3.1, j'obtiens l'avertissement suivant (qui conduit à l'arrêt de | la compilation) : | | warning: dereferencing type-punned pointer will break strict-aliasing rules | | Je pourrais bien sûr utiliser l'option de compilation | no-strict-aliasing, mais je suppose qu'il vaudrait mieux régler le | problème proprement.
Oui, il faut mieux. C'est la correction du programme qui est en jeu.
| J'ai trouvé quelques infos intéressantes en cherchant sur Google, par | exemple ce message qui m'a permis de comprendre (à peu près) le pb : | | http://www.ethereal.com/lists/ethereal-dev/200309/msg00343.html
L'explication donnée est correcte.
| La solution utilisée dans beaucoup de projets libres est apparemment | d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très | propre, même si c'était autorisé...
Non seulement ce n'est pas propre mais ce n'est pas correct non plus, du point de vue de la norme. Cependant, GCC donne la garantie que si tu utilises une union pour faire ce genre de tripafouillage, alors il fera son possible pour ne pas optimiser sous couvert d'aliasing strict. Je crois que beaucoup de compilateurs du monde réel donnent cette garantie mais il faudra vérifier.
| Questions : | | Quel est la traduction correcte de "type punning" ?
Je ne sais pas. Mais l'explication que tu as trouvée dans le lien est correcte.
| Est-ce que l'utilisation de cette technique révèle une erreur de | conception du programme ?
Ah très certainement :-)
| Pour info le programme en question est gnome-build, et l'erreur est la | suivante : | | typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char | *name); | | ... | | GluePluginGetTypeFunc get_type_func; | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est quoi gpointer? Un void*?
-- Gaby
Nicolas PENINGUY <np.news@free.fr> writes:
| Salut,
|
| Je pensais ne pas trop être mauvais en C, mais me voilà confronté à un
| élément de la norme C99 apparemment... En compilant un programme avec
| GCC 3.3.1, j'obtiens l'avertissement suivant (qui conduit à l'arrêt de
| la compilation) :
|
| warning: dereferencing type-punned pointer will break strict-aliasing rules
|
| Je pourrais bien sûr utiliser l'option de compilation
| no-strict-aliasing, mais je suppose qu'il vaudrait mieux régler le
| problème proprement.
Oui, il faut mieux. C'est la correction du programme qui est en jeu.
| J'ai trouvé quelques infos intéressantes en cherchant sur Google, par
| exemple ce message qui m'a permis de comprendre (à peu près) le pb :
|
| http://www.ethereal.com/lists/ethereal-dev/200309/msg00343.html
L'explication donnée est correcte.
| La solution utilisée dans beaucoup de projets libres est apparemment
| d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très
| propre, même si c'était autorisé...
Non seulement ce n'est pas propre mais ce n'est pas correct non
plus, du point de vue de la norme. Cependant, GCC donne la garantie
que si tu utilises une union pour faire ce genre de tripafouillage,
alors il fera son possible pour ne pas optimiser sous couvert
d'aliasing strict. Je crois que beaucoup de compilateurs du monde
réel donnent cette garantie mais il faudra vérifier.
| Questions :
|
| Quel est la traduction correcte de "type punning" ?
Je ne sais pas. Mais l'explication que tu as trouvée dans le lien est
correcte.
| Est-ce que l'utilisation de cette technique révèle une erreur de
| conception du programme ?
Ah très certainement :-)
| Pour info le programme en question est gnome-build, et l'erreur est la
| suivante :
|
| typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char
| *name);
|
| ...
|
| GluePluginGetTypeFunc get_type_func;
|
| ... (gpointer *)&get_type_func <-- c'est ici que ça coince
| Salut, | | Je pensais ne pas trop être mauvais en C, mais me voilà confronté à un | élément de la norme C99 apparemment... En compilant un programme avec | GCC 3.3.1, j'obtiens l'avertissement suivant (qui conduit à l'arrêt de | la compilation) : | | warning: dereferencing type-punned pointer will break strict-aliasing rules | | Je pourrais bien sûr utiliser l'option de compilation | no-strict-aliasing, mais je suppose qu'il vaudrait mieux régler le | problème proprement.
Oui, il faut mieux. C'est la correction du programme qui est en jeu.
| J'ai trouvé quelques infos intéressantes en cherchant sur Google, par | exemple ce message qui m'a permis de comprendre (à peu près) le pb : | | http://www.ethereal.com/lists/ethereal-dev/200309/msg00343.html
L'explication donnée est correcte.
| La solution utilisée dans beaucoup de projets libres est apparemment | d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très | propre, même si c'était autorisé...
Non seulement ce n'est pas propre mais ce n'est pas correct non plus, du point de vue de la norme. Cependant, GCC donne la garantie que si tu utilises une union pour faire ce genre de tripafouillage, alors il fera son possible pour ne pas optimiser sous couvert d'aliasing strict. Je crois que beaucoup de compilateurs du monde réel donnent cette garantie mais il faudra vérifier.
| Questions : | | Quel est la traduction correcte de "type punning" ?
Je ne sais pas. Mais l'explication que tu as trouvée dans le lien est correcte.
| Est-ce que l'utilisation de cette technique révèle une erreur de | conception du programme ?
Ah très certainement :-)
| Pour info le programme en question est gnome-build, et l'erreur est la | suivante : | | typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char | *name); | | ... | | GluePluginGetTypeFunc get_type_func; | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est quoi gpointer? Un void*?
-- Gaby
Gabriel Dos Reis
Emmanuel Delahaye writes:
| > La solution utilisée dans beaucoup de projets libres est apparemment | > d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très | > propre, même si c'était autorisé... | | C'est propre et c'est correct.
Faux.
-- Gaby
Emmanuel Delahaye <emdelYOURBRA@noos.fr> writes:
| > La solution utilisée dans beaucoup de projets libres est apparemment
| > d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très
| > propre, même si c'était autorisé...
|
| C'est propre et c'est correct.
| > La solution utilisée dans beaucoup de projets libres est apparemment | > d'utiliser un union, mais j'ai lu néanmoins que ce n'était pas très | > propre, même si c'était autorisé... | | C'est propre et c'est correct.
Faux.
-- Gaby
Gabriel Dos Reis
Nicolas PENINGUY writes:
| | > C'est propre et c'est correct. | | Je viens de faire la connerie de lire ce thread : | | http://groups.google.fr/groups?selm=clcm-20030916-0007%40plethora.net
C'est également correct.
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Pourquoi ?
-- Gaby
Nicolas PENINGUY <np.news@free.fr> writes:
|
| > C'est propre et c'est correct.
|
| Je viens de faire la connerie de lire ce thread :
|
| http://groups.google.fr/groups?selm=clcm-20030916-0007%40plethora.net
C'est également correct.
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
| | > C'est propre et c'est correct. | | Je viens de faire la connerie de lire ce thread : | | http://groups.google.fr/groups?selm=clcm-20030916-0007%40plethora.net
C'est également correct.
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Pourquoi ?
-- Gaby
Nicolas PENINGUY
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Pourquoi ?
Un ton trop sec, limite agressif souvent... C'est pas forcément facile pour quelqu'un qui maîtrise mal un domaine d'être parfaitement rigoureux, on peut le remettre dans le droit chemin avec le sourire.
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Pourquoi ?
Un ton trop sec, limite agressif souvent... C'est pas forcément facile
pour quelqu'un qui maîtrise mal un domaine d'être parfaitement
rigoureux, on peut le remettre dans le droit chemin avec le sourire.
| sur comp.lang.c.moderated et je suis traumatisé maintenant. :-)
Pourquoi ?
Un ton trop sec, limite agressif souvent... C'est pas forcément facile pour quelqu'un qui maîtrise mal un domaine d'être parfaitement rigoureux, on peut le remettre dans le droit chemin avec le sourire.
Nicolas PENINGUY
| typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char | *name); | | ... | | GluePluginGetTypeFunc get_type_func; | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince
C'est quoi gpointer? Un void*?
Oui c'est bien ça... En fait ça me semble relativement simple à corriger pour ce cas précis. Est-ce correct ?
/* Récupération de l'adresse d'une fonction dans un module */ g_module_symbol (..., &symbol); get_type_func = (GluePluginGetTypeFunc)symbol;
Merci
Gabriel Dos Reis
Nicolas PENINGUY writes:
| | > | typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char | > | *name); | > | | ... | > | | GluePluginGetTypeFunc get_type_func; | > | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince | > C'est quoi gpointer? Un void*? | | Oui c'est bien ça... En fait ça me semble relativement simple à | corriger pour ce cas précis. Est-ce correct ?
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur vers une donnée (void*) puisse représenter sans perte d'information un pointeur vers une fonction. En fait, un pointeur vers une fonction est une bête vraiment différente d'un pointeur vers une donnée.
Dans ce cas-ci, le cast probablement le plus portable est vers un void(void).
| gpointer symbol; | GluePluginGetTypeFunc get_type_func; | | ... | | /* Récupération de l'adresse d'une fonction dans un module */ | g_module_symbol (..., &symbol); | get_type_func = (GluePluginGetTypeFunc)symbol;
cela ne change pas le problème fondamental.
-- Gaby
Nicolas PENINGUY <np.news@free.fr> writes:
|
| > | typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char
| > | *name);
| > | | ...
| > | | GluePluginGetTypeFunc get_type_func;
| > | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince
| > C'est quoi gpointer? Un void*?
|
| Oui c'est bien ça... En fait ça me semble relativement simple à
| corriger pour ce cas précis. Est-ce correct ?
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur
vers une donnée (void*) puisse représenter sans perte d'information un
pointeur vers une fonction. En fait, un pointeur vers une fonction est
une bête vraiment différente d'un pointeur vers une donnée.
Dans ce cas-ci, le cast probablement le plus portable est vers un void(void).
| | > | typedef GType (*GluePluginGetTypeFunc) (GluePlugin *plugin, const char | > | *name); | > | | ... | > | | GluePluginGetTypeFunc get_type_func; | > | | ... (gpointer *)&get_type_func <-- c'est ici que ça coince | > C'est quoi gpointer? Un void*? | | Oui c'est bien ça... En fait ça me semble relativement simple à | corriger pour ce cas précis. Est-ce correct ?
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur vers une donnée (void*) puisse représenter sans perte d'information un pointeur vers une fonction. En fait, un pointeur vers une fonction est une bête vraiment différente d'un pointeur vers une donnée.
Dans ce cas-ci, le cast probablement le plus portable est vers un void(void).
| gpointer symbol; | GluePluginGetTypeFunc get_type_func; | | ... | | /* Récupération de l'adresse d'une fonction dans un module */ | g_module_symbol (..., &symbol); | get_type_func = (GluePluginGetTypeFunc)symbol;
cela ne change pas le problème fondamental.
-- Gaby
Nicolas PENINGUY
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur vers une donnée (void*) puisse représenter sans perte d'information un pointeur vers une fonction. En fait, un pointeur vers une fonction est une bête vraiment différente d'un pointeur vers une donnée.
Effectivement je pensais à tord qu'un pointeur sur void pouvait servir à représenter un pointeur sur une fonction...
C'est donc cette fonction de la glib qui serait incorrecte :
/* Gets a symbol pointer from a module. */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol);
Celà dit je me demande si par symbol on entend seulement un pointeur sur une fonction... Je ne me sens pas non plus le courage d'aller me plaindre du côté des développeurs de la glib. :-)
Merci pour ces précisions, on en apprends tous les jours :-)
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur
vers une donnée (void*) puisse représenter sans perte d'information un
pointeur vers une fonction. En fait, un pointeur vers une fonction est
une bête vraiment différente d'un pointeur vers une donnée.
Effectivement je pensais à tord qu'un pointeur sur void pouvait servir à
représenter un pointeur sur une fonction...
C'est donc cette fonction de la glib qui serait incorrecte :
/* Gets a symbol pointer from a module. */
gboolean g_module_symbol (GModule *module,
const gchar *symbol_name,
gpointer *symbol);
Celà dit je me demande si par symbol on entend seulement un pointeur sur
une fonction... Je ne me sens pas non plus le courage d'aller me
plaindre du côté des développeurs de la glib. :-)
Merci pour ces précisions, on en apprends tous les jours :-)
Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur vers une donnée (void*) puisse représenter sans perte d'information un pointeur vers une fonction. En fait, un pointeur vers une fonction est une bête vraiment différente d'un pointeur vers une donnée.
Effectivement je pensais à tord qu'un pointeur sur void pouvait servir à représenter un pointeur sur une fonction...
C'est donc cette fonction de la glib qui serait incorrecte :
/* Gets a symbol pointer from a module. */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol);
Celà dit je me demande si par symbol on entend seulement un pointeur sur une fonction... Je ne me sens pas non plus le courage d'aller me plaindre du côté des développeurs de la glib. :-)
Merci pour ces précisions, on en apprends tous les jours :-)
Gabriel Dos Reis
Nicolas PENINGUY writes:
| | > Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur | > vers une donnée (void*) puisse représenter sans perte d'information un | > pointeur vers une fonction. En fait, un pointeur vers une fonction est | > une bête vraiment différente d'un pointeur vers une donnée. | | Effectivement je pensais à tord qu'un pointeur sur void pouvait servir | à représenter un pointeur sur une fonction... | | C'est donc cette fonction de la glib qui serait incorrecte : | | /* Gets a symbol pointer from a module. */ | gboolean g_module_symbol (GModule *module, | const gchar *symbol_name, | gpointer *symbol); | | Celà dit je me demande si par symbol on entend seulement un pointeur | sur une fonction... Je ne me sens pas non plus le courage d'aller me | plaindre du côté des développeurs de la glib. :-)
Je ne suis pas certain que le type du paramètre symbol doit être « gpointer* ». Je crois qu'un simple « gpointer » suffit.
En effet, un pointeur vers une fonction est une donnée, donc un pointeur vers un pointeur vers une fonction est parfaitement (et implicitement) convertible vers un « void* ».
Par exemple, en supposant que la fonction g_module_symbol soit déclarée comme
/* Gets a symbol pointer from a module. */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer symbol);
C'est à l'implémenteur de g_module_symbol de se débrouiller s'il veut supporter aussi l'interrogation pour les pointeurs vers fonctions.
-- Gaby
Nicolas PENINGUY <np.news@free.fr> writes:
|
| > Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur
| > vers une donnée (void*) puisse représenter sans perte d'information un
| > pointeur vers une fonction. En fait, un pointeur vers une fonction est
| > une bête vraiment différente d'un pointeur vers une donnée.
|
| Effectivement je pensais à tord qu'un pointeur sur void pouvait servir
| à représenter un pointeur sur une fonction...
|
| C'est donc cette fonction de la glib qui serait incorrecte :
|
| /* Gets a symbol pointer from a module. */
| gboolean g_module_symbol (GModule *module,
| const gchar *symbol_name,
| gpointer *symbol);
|
| Celà dit je me demande si par symbol on entend seulement un pointeur
| sur une fonction... Je ne me sens pas non plus le courage d'aller me
| plaindre du côté des développeurs de la glib. :-)
Je ne suis pas certain que le type du paramètre symbol doit être
« gpointer* ». Je crois qu'un simple « gpointer » suffit.
En effet, un pointeur vers une fonction est une donnée, donc un
pointeur vers un pointeur vers une fonction est parfaitement (et
implicitement) convertible vers un « void* ».
Par exemple, en supposant que la fonction g_module_symbol soit
déclarée comme
/* Gets a symbol pointer from a module. */
gboolean g_module_symbol (GModule *module,
const gchar *symbol_name,
gpointer symbol);
| | > Non, ce n'est pas correct. Il n'y a aucune garantie qu'un pointeur | > vers une donnée (void*) puisse représenter sans perte d'information un | > pointeur vers une fonction. En fait, un pointeur vers une fonction est | > une bête vraiment différente d'un pointeur vers une donnée. | | Effectivement je pensais à tord qu'un pointeur sur void pouvait servir | à représenter un pointeur sur une fonction... | | C'est donc cette fonction de la glib qui serait incorrecte : | | /* Gets a symbol pointer from a module. */ | gboolean g_module_symbol (GModule *module, | const gchar *symbol_name, | gpointer *symbol); | | Celà dit je me demande si par symbol on entend seulement un pointeur | sur une fonction... Je ne me sens pas non plus le courage d'aller me | plaindre du côté des développeurs de la glib. :-)
Je ne suis pas certain que le type du paramètre symbol doit être « gpointer* ». Je crois qu'un simple « gpointer » suffit.
En effet, un pointeur vers une fonction est une donnée, donc un pointeur vers un pointeur vers une fonction est parfaitement (et implicitement) convertible vers un « void* ».
Par exemple, en supposant que la fonction g_module_symbol soit déclarée comme
/* Gets a symbol pointer from a module. */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer symbol);