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 :

function declaration isn't a prototype


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut function declaration isn't a prototype
    Bonjour,
    Je déclare un type de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef t_sender *(*sender_initializer)();
    et j'obtiens le warning du titre :
    function declaration isn't a prototype
    J'utilise gcc 4.2.2.
    Que signifie exactement ce warning ? La construction n'est pas licite ? Je l'utilise pour déclarer un pointeur de fonction pouvant prendre n'importe quelle liste de paramètres. Le warning disparaît si je met void entre parenthèses mais ce n'est pas ce que je veux...
    Quelle est l'option qui permet de faire disparaître ce warning ? Et surtout est-ce sûr de faire disparaître le warning en question ?

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut



    Un typedef pour créer un pointeur de fonction ne se fait que de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef type_retour (* nom_pointeur) (type_argument *);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef type_retour * (* nom_pointeur) (type_argument *);
    Pour la seconde forme je crois que c'est aussi juste même si je ne l'ai jamais utilisé en réalité.

    Si tu montrais ton code ca irais peut-être mieux, tu es sûr que l'erreur ne viens réellement pas d'autre part ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut

    Je ne comprend pas, il me semblait qu'on pouvait mettre des parenthèses vides pour indiquer qu'on ne voulait pas vérifier les paramètres de la fonction ?

    Et puis ce qui m'étonne c'est que le warning n'apparaît pas partout, en effet sous ubuntu, rien n'apparaît (gcc 4.4.1 flags -W -Wall -std=c99 -Iinclude -D_POSIX_SOURCE -Werror -g).
    Le warning apparaît sous XP avec gcc 4.2.2 et 3.2.1.

    ...

    Arf, il semble que sous win il y ait le flag -Wstrict-prototypes et après test, en activant ce flag, j'ai le même warning sour ubuntu.

    Moi je veux un pointeur de fonction retournant un pointeur sur sender_t et acceptant n'importe quelle liste de paramètres. C'est bien licite non ?

    Concernant tes exemples de code, les deux lignes sont le même genre de construction si je comprends bien, sauf que le premier concerne des fonctions renvoyant des variables de type type_retour alors que le second concerne des fonctions renvoyant des pointeurs sur des variables de type type_retour.

    Moi je sens que je vais transtyper tout ça en void * ...


    PS désolé pour l'abus de smiley, mais je viens juste de découvrir la liste supplémentaire ...

    [Edit]Pour ce qui est du code, je ne sais vraiment pas quoi montrer puisque seule cette ligne cause un warning...

  4. #4
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Je suis sur Ubuntu effectivement

    Citation Envoyé par huit_six Voir le message
    Moi je veux un pointeur de fonction retournant un pointeur sur sender_t et acceptant n'importe quelle liste de paramètres. C'est bien licite non ?
    Oui mais dans ce cas il faut tout de même spécifier au moins un void* en argument car je crois qu'implicitement gcc met void si tu ne met pas d'argument, ca je suis pas sûr mais c'est logique.

    Citation Envoyé par huit_six Voir le message
    Concernant tes exemples de code, les deux lignes sont le même genre de construction si je comprends bien, sauf que le premier concerne des fonctions renvoyant des variables de type type_retour alors que le second concerne des fonctions renvoyant des pointeurs sur des variables de type type_retour.
    Oui
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Oui mais dans ce cas il faut tout de même spécifier au moins un void* en argument car je crois qu'implicitement gcc met void si tu ne met pas d'argument, ca je suis pas sûr mais c'est logique.
    Je ne comprend pas :
    * Si je met void * alors les seules fonctions compatibles seront celles attendant un paramètre de type void *
    * Si je met void alors les seules fonctions compatibles seront celles n'attendant aucun paramètre
    ou est-ce que je me trompe ?
    [Edit] Arglllgl ! Eclipse vient de planter ! je vais jamais réussir à déboguer sur ce fichu boîtier arm... Déjà que je code sous ubuntu et que je suis obligé de transférer sous XP pour compiler et envoyer sur le boîtier... la vie est injuste !

  6. #6
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par huit_six Voir le message
    Je ne comprend pas :
    * Si je met void * alors les seules fonctions compatibles seront celles attendant un paramètre de type void *
    * Si je met void alors les seules fonctions compatibles seront celles n'attendant aucun paramètre
    ou est-ce que je me trompe ?
    Tu as juste Réfléchi... si tu met un paramètre void* il te suffit de transtyper l'argument dans le bon type dans ta fonction, c'est le principe même de la généricité en C !

    Ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void fonction (void * p)
    {
       liste * ma_liste = (liste *) p;
     
       /* ... */
    }
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Je comprend bien, mais ce n'est pas seulement le type mais également le nombre de mes arguments qui peut changer...

  8. #8
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par huit_six Voir le message
    Je comprend bien, mais ce n'est pas seulement le type mais également le nombre de mes arguments qui peut changer...
    Alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef type_retour * (* nom_pointeur) (type_argument *, ...);
    Liste variable d'arguments mais c'est la seule et unique solution
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    Hum ok, ça me va ! et comme mes paramètres seront des chaînes de caractères, ça devrait donner un truc dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef t_sender *(*sender_initializer)(char * arg1, ...);
    Par contre, pour le coup des parenthèses vides, il me semblait bien l'avoir entendu quelque part... Peut être un reste d'une ancienne forme, vu que la syntaxe du passage de paramètres a évolué...

    Dans tous les cas :

  10. #10
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par huit_six Voir le message
    Par contre, pour le coup des parenthèses vides, il me semblait bien l'avoir entendu quelque part... Peut être un reste d'une ancienne forme, vu que la syntaxe du passage de paramètres a évolué...
    Liste de paramètres vide ca se faisait à une époque mais le compilateur mettais alors implicitement void !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  11. #11
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    @huit_six : c'est juste un warning (le compilateur dit juste qu'il espère que tu sais ce que tu fais), ça ne signifie pas que ton code n'est pas conforme à la norme. Ton type sender_initializer peut très bien pointer sur n'importe quelle fonction qui retourne un t_sender *, peu importe les arguments requis par la fonction. Déclarer une fonction sans prototype (en gros sans les informations complètes sur la valeur de retour les arguments requis) est cependant une pratique obsolète et réputée dangereuse (lors d'un appel à la fonction, le compilateur ne pourra vérifier si les arguments passés sont bons ou non ...). Poste tout ton code si tu veux qu'on puisse te conseiller sur les manières recommandées de coder en C.

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 184
    Points : 288
    Points
    288
    Par défaut
    @melem: Après réflexion, il semble plutôt que ce soit un problème de conception qui m'ait amené à ce genre de construction. Je m'explique.
    J'ai des modules qui "implémentent" une "classe abstraite" sender.h pour l'envoi de données sur internet. Chaque implémentation spécifie une méthode d'envoi et possède sa propre fonction d'initialisation qui renvoie un t_sender *, type utilisé pour faire les envois effectifs.

    Pour l'instant, j'ai créé un tableau de pointeurs sur les fonctions d'initialisation de chaque module et une enum avec des constantes symboliques représentant les méthodes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    typedef t_sender *(*sender_initializer)();
    typedef enum send_method {
    	POST_SEND
    }send_method;
     
    const sender_initializer init_send_method[] = {init_post_send};
    Le but était d'initialiser mon module avec un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    send_method method = POST_SEND;
    t_sender *sender = init_send_method[method](/* paramètres */);
    L'idée était pas mal puisque a permettait de s'éviter plusieurs switch (sachant qu'il devait y avoir, à terme 4 ou 5 méthodes d'envoi, voire plus et utilisées en plusieurs endroits). Mais le hic, c'est justement que les paramètres d'initialisation ne sont pas les mêmes d'une méthode d'envoi à l'autre et donc, j'aurai de toute manière dû ajouter un switch. Là ou je me suis fait avoir, c'est que comme pour l'instant je n'ai codé qu'une méthode et le problème n'était donc pas encore apparu...

    En tout cas, merci à vous.

    Je crois qu'on pourrait ériger ceci en règle de bonne pratique de programmation :
    Quand tu es face à un problème apparemment insoluble, reprends à zéro ta conception...

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

Discussions similaires

  1. [VBA-E]function sub declaration
    Par trach.sam dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 11/08/2006, 20h14
  2. implicit declaration of function!
    Par moon93 dans le forum C
    Réponses: 48
    Dernier message: 16/06/2006, 14h55
  3. implicit declaration of function
    Par guillaume_pfr dans le forum C
    Réponses: 7
    Dernier message: 12/06/2003, 10h59
  4. [Dev c++ 4] implicite declaration of function "int kbhi
    Par Torpedox dans le forum Dev-C++
    Réponses: 5
    Dernier message: 01/01/2003, 13h37

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