IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

warning: ISO C forbids assignment between function pointer and `void *'


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 41
    Par défaut warning: ISO C forbids assignment between function pointer and `void *'
    *Bonjour*

    Tout est dans le titre. Si vous savez comment solutionner ça, je suis preneur.

    *Merci d'avance*

  2. #2
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    hook.c:7: warning: ISO C forbids assignment between function pointer and `void *'
    hook.c:8: warning: ISO C forbids assignment between function pointer and `void *'
    La norme du C n'exige pas qu'un pointeur sur un objet sur void puisse être converti en pointeur sur une fonction. Assigner un void * à un pointeur de fonction est donc une opération non portable, d'où le warning. Une manière de contourner le warning (autre que le désactiver) sans toutefois résoudre le problème de portabilité : utiliser memcpy au lieu de l'affectation.
    wrapper.c:19: warning: ISO C89 forbids specifying subobject to initialize
    wrapper.c:20: warning: ISO C89 forbids specifying subobject to initialize
    Ici la syntaxe est tout simplement non standard, il faut initialiser l'objet pendant sa définition ou alors appeler écrire une fonction d'initialisation pour être 100% conforme et donc portable.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 469
    Par défaut
    Citation Envoyé par Melem Voir le message
    Assigner un void * à un pointeur de fonction est donc une opération non portable, d'où le warning. Une manière de contourner le warning (autre que le désactiver) sans toutefois résoudre le problème de portabilité : utiliser memcpy au lieu de l'affectation.
    Euh… je n'ai que survolé le problème, mais memcpy(), ça me paraît un peu lourd, quand même. Un simple cast ne serait-il pas justifié dans le cas présent (utilisation de dlsym()) ?

  4. #4
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Je ne pense pas que l'ajout d'un cast puisse supprimer ce warning car le résultat sera le même : tu convertis toujours, par cast, un void * en pointeur de fonction, ce qui n'est pas portable. Mais c'est vrai qu'il faut tenter car je viens de me rendre compte que même le memcpy ne résout pas l'affaire. Si le cast non plus ne marche pas, et ben comme le code n'est pas portable, le seul moyen de supprimer le warning c'est de faire taire le compilateur (enlever aussi -pedantic et/ou -Wall et/ou -W).

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 469
    Par défaut
    Effectivement, si j'essaie sous GCC de transtyper « void * » vers le pointeur de fonction adéquat, j'obtiens une erreur parce que le compilateur considère que le pointeur, tout void soit-il, reste un pointeur d'objet et donc ne peut être transformé en pointeur de fonction :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main (void)
    {
        hook_t h;
     
        h._open  = (int(*)(const char *,int,mode_t))dlsym( RTLD_NEXT, "open");
        h._close = (int(*)(int))dlsym( RTLD_NEXT, "close" );
     
        return 0;
    }

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ gcc -pedantic -ansi -W -Wall funcptrcast.c -o funcptrcast
    funcptrcast.c: In function ‘main’:
    funcptrcast.c:5: attention : ISO C interdit la conversion d'un pointeur d'objet vers un type de pointeur à une fonction
    funcptrcast.c:6: attention : ISO C interdit la conversion d'un pointeur d'objet vers un type de pointeur à une fonction

    C'est d'ailleurs très discutable parce que ça aurait du sens sur les architectures purement Harvard, mais ça devrait être une exception gérée par le compilo concerné et pas une généralité de la norme C puisqu'il est établi qu'un pointeur, en général, peut très bien accéder une zone de mémoire contenant du code sur la plupart des architectures conventionnelles.

    Par contre, le contraire fonctionne bien !

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        *(void **)&(h._open)  = dlsym( RTLD_NEXT, "open");
        *(void **)&(h._close) = dlsym( RTLD_NEXT, "close" );

    C'est même sensiblement plus lisible parce que plus court, moins complexe et parce que le type est le même à chaque appel.

    ÉDIT : La norme C99 (enfin, n1256) spécifie explicitement cette possibilité :

    J.5.7 Function pointer casts
    1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to
    be invoked as a function (6.5.4).
    2 A pointer to a function may be cast to a pointer to an object or to void, allowing a
    function to be inspected or modified (for example, by a debugger) (6.5.4).
    Mais GCC cesse de se plaindre également dès lors que l'on enlève « -pedantic », même avec « -std=c89 ». La man page de GCC spécifie :

    Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

    […]

    Some users try to use -pedantic to check programs for strict ISO C conformance. They soon find that it does not do quite what they want: it finds some non-ISO practices, but not all---only those for which ISO C requires a diagnostic, and some others for which diagnostics have been added.
    Je ne sais pas dans quelle section de la norme ces contrôles stricts sont définis.

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2011
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 41
    Par défaut
    Ca marche !
    Enfin disparus ces warnings et le code fonctionne toujours !

    Merci à tous pour votre aide.

    Obsidian est un authentique guru, merci à lui de prendre le temps de faire part de son savoir à des développeurs de mon niveau.

    A l'occasion, il faudra que tu m'orientes sur un échange en MP ou un tuto balaise pour que je comprenne ces cast de fonctions qui me semblent encore bien mystérieux.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ISO C++ forbids declaration of SHA1
    Par ikuzar dans le forum Débuter
    Réponses: 6
    Dernier message: 21/02/2011, 11h42
  2. comparison between pointer and integer
    Par sculpteur dans le forum Objective-C
    Réponses: 1
    Dernier message: 03/12/2010, 17h31
  3. Réponses: 3
    Dernier message: 20/08/2009, 20h46
  4. ISO C++ forbids declaration
    Par inddzen dans le forum C++
    Réponses: 17
    Dernier message: 20/01/2008, 18h23
  5. Réponses: 9
    Dernier message: 15/02/2005, 13h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo