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 :

Taille d'une va_list


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut Taille d'une va_list
    Bonjour à tous,

    Je suppose que la question a déjà été posée des dizaines de fois, malheureusement, je n'ai pas trouvé de réponse avec la recherche...

    La question est la suivante : est-il possible de connaître le nombre d'éléments que contient une va_list ?

    Présentement, j'utilise un marqueur de fin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    /**
     * Fonction permettant de creer un tableau dynamique
     * @param iDataType le type des donnees qui suivent
     * @param ... les données, pouvant etre des chaines, des booleens, des 
     * entiers, ou des GType. Il faut obligatoirement terminer par un
     * G_TYPE_INVALID
     * @return pointeur vers notre structure
     */
    CidDataTable *
    cid_create_datatable (GType iDataType, ...)
    {
        CidDataTable *res = cid_datatable_new();
        GType iCurrType = iDataType;
        va_list args;
        va_start(args,iDataType);
        void *current;
        while ((current = va_arg(args,void *)) != G_TYPE_INVALID) {
            CidDataContent *tmp = NULL;
            if ((GType) current == G_TYPE_BOOLEAN || (GType) current == G_TYPE_INT || (GType) current == G_TYPE_STRING)
            {
                iCurrType = (GType) current;
                continue;
            }
            switch (iCurrType) 
            {
                case G_TYPE_BOOLEAN:
                    tmp = cid_datacontent_new_boolean(current);
                    break;
                case G_TYPE_STRING:
                    tmp = cid_datacontent_new_string(current);
                    break;
                case G_TYPE_INT:
                    tmp = cid_datacontent_new_int(current);
                    break;
                default:
                    iCurrType = (GType) current;
            }
            res = cid_datatable_append(res,tmp);
        }
        va_end(args);
        return res;
    }
    Mais existe-t-il un moyen de savoir combien de paramètres optionnels ont été entrés ?

  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 : 48
    Localisation : France, Haut Rhin (Alsace)

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

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



    Tu parcours la va_list et à chaque itération de la boucle tu incrémentes un compteur de 1.
    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 chevronné Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Par défaut
    Citation Envoyé par BSans Voir le message
    La question est la suivante : est-il possible de connaître le nombre d'éléments que contient une va_list ?
    Non, seul l'appelant connait le nombre de paramètres qu'il a mis sur la pile.
    Il y aurait peut être une possibilité mais il faut faire de l'assembleur pour regarder et comparer les pointeurs de pile, de frame et autres pointeurs. Personnellement, je ne m'y risquerait pas.

    Citation Envoyé par BSans Voir le message
    Présentement, j'utilise un marqueur de fin :
    continue

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Merci pour ces réponses rapides !

    En conclusion, il n'y a aucun autre moyen de "protéger" la fonction que le marqueur de fin ?

    Une autre technique serait d'utiliser un paramètre int nb_elem, mais ça revient au même niveau "sécurité" ; il faut faire confiance au développeur qui utilisera la fonction.

  5. #5
    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 : 48
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par BSans Voir le message
    En conclusion, il n'y a aucun autre moyen de "protéger" la fonction que le marqueur de fin ?

    Une autre technique serait d'utiliser un paramètre int nb_elem, mais ça revient au même niveau "sécurité" ; il faut faire confiance au développeur qui utilisera la fonction.
    Tout à fait Le mieux reste encore de finir la liste avec une valeur comme NULL par exemple !
    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 !

  6. #6
    Membre chevronné Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Par défaut
    Citation Envoyé par BSans Voir le message
    En conclusion, il n'y a aucun autre moyen de "protéger" la fonction que le marqueur de fin ?
    Pas à ma connaissance

    Citation Envoyé par BSans Voir le message
    Une autre technique serait d'utiliser un paramètre int nb_elem, mais ça revient au même niveau "sécurité" ;
    Tout à fait

    Citation Envoyé par BSans Voir le message
    il faut faire confiance au développeur qui utilisera la fonction.
    Oui !!

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Tout à fait Le mieux reste encore de finir la liste avec une valeur comme NULL par exemple !
    Oui. J'utilise en fait la valeur G_TYPE_INVALID pour signaler la fin de ma liste.

    Et donc, une dérivée de la question initiale.

    Peut-on "concaténer" un argument manuellement ?

    Dans l'idée, on obtiendrait quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void ma_vraie_fonction (char *blah, va_list list);
     
    void ma_fonction (char *blah, ...)
    {
        va_list args;
        va_start (args, blah);
        /* ici on concatène args avec G_TYPE_INVALID */
        ma_vraie_fonction (blah, args);
        va_end (args);
    }

  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 : 48
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    J'ai déjà essayé par le passé pour un projet de faire des modifications dans une va_list mais cela n'est pas trop possible et si ca l'est, très risqué.
    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 éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Ok, encore merci.

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 162
    Billets dans le blog
    152
    Par défaut
    Bonjour,

    Je pense pouvoir aidé un peu sur cette question. Moi même j'ai eu des gros problèmes avec les va_list.
    En fait, il existe une fonction 'snprintf()'

    Voici le manpage que j'ai (en anglais pardon)
    Concerning the return value of snprintf(), SUSv2 and C99 contradict
    each other: when snprintf() is called with size=0 then SUSv2 stipulates
    an unspecified return value less than 1, while C99 allows str to be
    NULL in this case, and gives the return value (as always) as the number
    of characters that would have been written in case the output string
    has been large enough
    Qui dit, que dans une implémentation C99 (bon, c'est pas le C ultra strict), on peut passer un pointeur null, qui permettra d'avoir la taille de la chaine que l'on doit avoir en résultat. ( Je pense que cela répondra en partie à votre réponse, même si vous ne demander pas la même chose ).
    Dans le cas, ou vous n'avez pas l'implementation comme dans la norme C99, vous pouvez trouvé le code source de celle ci sur internet et le mettre dans votre code. Comme ça, pas besoin de trop se poser de question ( et en même temps on apprend comme c'est géré )

    En espérant que cela aide
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    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 : 48
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Ca ne devrait même pas exister le C99 (sans vouloir lancer de débat)
    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 !

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Je ne sais pas si je m'y suis bien pris, mais mon implémentation ne fonctionne pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    BSans $ cat main.c 
    #include <stdlib.h>
    #include <stdio.h>
     
    int main (int argc, char **argv)
    {
        int nb = snprintf(NULL,0,NULL,"toto","tata","titi","a",'b');
        fprintf(stdout,"params: %d\n",nb);
     
        return EXIT_SUCCESS;
    }
    BSans $ gcc -std=c99 -c main.c 
    BSans $ gcc -std=c99 -o test main.o
    BSans $ ./test 
    params: -1

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    snprintf() ne retourne pas le nombre de paramètres, mais le nombre de caractères nécessaires: Tu dois donc spécifier un format pour que ça puisse être calculé.
    Là, tu passes NULL à la place, donc snprintf() refuse.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdlib.h>
    #include <stdio.h>
     
    int main (int argc, char **argv)
    {
    	int nb = snprintf(NULL, 0, "%s%s%s %s %c\n", "toto", "tata", "titi", "a", 'b');
    	fprintf(stdout,"taille: %d\n", nb);
     
    	return EXIT_SUCCESS;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Donc aucun intérêt pour le problème que j'exposais plus tôt.

    Il est impossible de déterminer le format des arguments à l'avance, comme il est impossible de prévoir le nombre d'arguments optionnels que l'utilisateur entrera.

  15. #15
    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 : 48
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par BSans Voir le message
    Donc aucun intérêt pour le problème que j'exposais plus tôt.

    Il est impossible de déterminer le format des arguments à l'avance, comme il est impossible de prévoir le nombre d'arguments optionnels que l'utilisateur entrera.
    Exactement
    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 !

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

Discussions similaires

  1. Comment calculer la taille d'une base de données ?
    Par say dans le forum Décisions SGBD
    Réponses: 8
    Dernier message: 01/04/2011, 16h48
  2. Réponses: 10
    Dernier message: 22/05/2004, 13h51
  3. [SQL SERVEUR]taille d'une base de donnée
    Par hirochirak dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 08/01/2004, 12h07
  4. : Adapter la taille d'une grille
    Par SteelBox dans le forum C++Builder
    Réponses: 3
    Dernier message: 31/07/2003, 07h08
  5. Taille d'une console sous linux
    Par Shinjuku dans le forum C
    Réponses: 7
    Dernier message: 13/06/2003, 12h44

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