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 :

[syntaxe] erreur de compilation pas comprise


Sujet :

C++

  1. #1
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut [syntaxe] erreur de compilation pas comprise
    Salut,

    Avant tout, j'ai r�solu mon probl�me je ne suis pas bloqu�, mais je ne comprends pas l'erreur, alors je voulais vous demander.


    voici ma question du jour. sachant que j'ai une classe:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    class VideoParser {
    public:
        VideoParser(std::string filename);
        ~VideoParser();
        void read();
     
    };
    pourquoi ceci compile:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
        string filename(argv[1]);
        VideoParser videoParser(filename);
        videoParser.read();
    tandis que ceci, non :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
        VideoParser videoParser( string(argv[1]) );
        videoParser.read();
    voici l'erreur :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    In function «int main(int, char**)":
    erreur: request for member «read" in «videoParser", which is of non-class type «VideoParser () (std::string*)"

  2. #2
    Membre �prouv�
    Inscrit en
    Mai 2007
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 43

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Par d�faut
    argv[1] est un char* et donc je pense que si tu le passes directement ca marche mieux...

    un cast c'est plutot comme ca: ((std::string)argv[1])
    si tu fais std::string mastring;
    mastring = "abcd..."; la camarche
    mastring = std::string("abcd..."); ne fonctionnera pas;

    par contre std::string *mastring = new std::string("asdf"); fonctionnera.

  3. #3
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    je comprends pas ce que tu veut dire.

    ma fonction je lui passe un string qui est construit � partir d'une chaine de caract�re (char*), et pourtant ca marche pas: pourquoi?

  4. #4
    Membre �prouv�
    Inscrit en
    Mai 2007
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 43

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Par d�faut
    D�sol�, j'avais valid� avant de finir la reponse....

    Quand tu fais un string(machaine); ca te retourne un std::string *
    Le constructeur de ta classe est bas� sur un std::string.

    Le probl�me vient de la

  5. #5
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    std::string() renvoie un std::string* ?

    je savais pas, je pensais que par convention le constructeur renvoyait un objet et qu'on avait pas � se soucier de sa destruction (contrairement � l'aide du mot cl� new).

    Ce n'est pas le cas pour std::string ?

  6. #6
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    La bonne habitude � prendre est de passer les param�tres au constructeurs sous forme de r�f�rence constante, surtout quand il s'agit de types "utilisateurs" (structures ou classes... fussent-elles fournies par une biblioth�que )

    L'avantage, c'est qu'il y a alors moyen de faire passer une cha�ne "C style" comme param�tre:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class VideoParser {
    public:
        VideoParser(const std::string& filename);
        ~VideoParser();
        void read();
     
    };
    te permet d'utiliser le constructeur sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    int main(int argc, char* argv)
    {
        /* normalement il y a intérêt à vérifier les arguments passés ;) */
        VideoParser parser(argv[1]);
        parser.read();
        /* ... */
    }
    Autrement, la premi�re chose que tu devra faire est... de convertir ta chaine "C style" en ... std::string
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  7. #7
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    c'est tr�s gentil (car c'est un bon conseil), mais ca r�pond pas � ma question

  8. #8
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Ma premi�re r�ponse est, quand m�me beaucoup plus proche de celle que tu attends que cela ne semble de prime abord:

    L'avantage de passer une r�f�rence (constante) comme param�tre est que tu ne n�cessite pas de recopie, et que cela permet de travailler plus correctement:

    Dans le code
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
        string filename(argv[1]);
        VideoParser videoParser(filename);
        videoParser.read();
    tu travailles en deux temps:

    Tu construit une variable de type std::string et nomm�e filename sur base du char* r�cup�r� en argv[1], ce qui est parfaitement autoris� parce qu'il y a un constructeur std::string::string(const char*) dans la classe string.

    Puis, tu appel le constructeur de VideoParser en lui fournissant une copie (appel � std::string(const std::string&)) d'une cha�ne correcte.

    Dans le deuxi�me exemple:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
     
        VideoParser videoParser(string (argv[1]));
        videoParser.read();
    la partie "string (argv[1])" cr�e une variable temporaire non nomm�e de type std::string... Et c'est une copie de cette variable temporaire qui est sens�e �tre fournie � VideoParser::VideoParser(std::string)

    Le probl�me, c'est que la std::string ne dispose pas d'un constructeur par copie prenant une std::string non constante (le constructeur par copie de std::string est std::string::string(const std::string&))... et donc, ne sait pas fournir la std::string nomm� "filename" au constructeur de VideoParser
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  9. #9
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 299
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 299
    Billets dans le blog
    2
    Par d�faut
    Citation Envoy� par mamelouk
    std::string() renvoie un std::string* ?
    Non. C'est qui renvoie un std::string*

    En revanche, tu poses une bonne question. Prenons un exemple qui utilise la classe suivante:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    class Dum
    {
    public:
    	Dum(const std::string &str):str_(str){}
    	std::string str_;
    };
    Pourquoi est-ce que ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    int main(int argc, char** argv)
    {
    	Dum dum( std::string(argv[1]) );
    //code
    }
    ne fonctionne pas, alors que ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    int main(int argc, char** argv)
    {
    	std::string str = std::string(argv[1]);
    	Dum dum( str );
    // code
    }
    fonctionne

    La compilation du premier main (sous visual8) me donne quelque chose d'�trange. J'obtiens ce warning:
    warning C4930: 'Dum dum(std::string [])': prototyped function not called (was a variable definition intended?)
    et �a compile, mais l'objet dum n'est pas cr�� � l'ex�cution.

  10. #10
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    eh bien c'est bizarre si ca compile, peut etre que le compilateur a optimis� ton code ; la variable n'est pas utilis� donc vir� des sources;

    par contre, la r�ponse � ma question semble etre ce que disait koala:

    Citation Envoy� par koala01
    Le probl�me, c'est que la std::string ne dispose pas d'un constructeur par copie prenant une std::string non constante (le constructeur par copie de std::string est std::string::string(const std::string&))... et donc, ne sait pas fournir la std::string nomm� "filename" au constructeur de VideoParser
    mais alors pour quoi ce code fonctionne:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
        string filename(argv[1]);
        VideoParser videoParser(filename);
        videoParser.read();
    alors que filename n'est pas d�clar� const ?

  11. #11
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 299
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 299
    Billets dans le blog
    2
    Par d�faut
    Citation Envoy� par mamelouk
    eh bien c'est bizarre si ca compile, peut etre que le compilateur a optimis� ton code ; la variable n'est pas utilis� donc vir� des sources;
    J'ai compil� en mode debug. Il ne vire rien en mode debug.

    par contre, la r�ponse � ma question semble etre ce que disait koala:
    Je ne crois pas. Ou alors j'ai mal compris. Je ne comprends pas pourquoi le compilo arrive � cr�er une string comme ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::string str = std::string(argv[1]);
    mais qu'il n'arrive pas � en cr�er une dans ce cas l�:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Dum dum( std::string(argv[1]) );
    Je pense qu'il y a une histoire de variable non nomm�e, mais je ne vois pas trop le rapport.

    mais alors pour quoi ce code fonctionne alors que filename n'est pas d�clar� const ?
    Car le compilo fait un const_cast automatiquement et de fa�on cach�e dans ce cas.

  12. #12
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    oui en fait, pareil que toi, j'ai �dit� mon message apr�s

  13. #13
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par mamelouk
    eh bien c'est bizarre si ca compile, peut etre que le compilateur a optimis� ton code ; la variable n'est pas utilis� donc vir� des sources;

    par contre, la r�ponse � ma question semble etre ce que disait koala:



    mais alors pour quoi ce code fonctionne:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
        string filename(argv[1]);
        VideoParser videoParser(filename);
        videoParser.read();
    alors que filename n'est pas d�clar� const ?
    Parce que ce n'est pas une variable temporaire...

    Le probl�me n'est pas tant le fait qu'une std::string fournie en param�tre soit const ou non avant qu'on ne la passe en param�tre, le probl�me est que ce ne peut pas �tre une variable temporaire

    Effectivement, le compilateur sait faire un const_cast de mani�re silencieuse... � condition qu'il dispose d'un objet ... non temporaire sur lequel l'appliquer
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  14. #14
    Membre �m�rite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par d�faut
    L'erreur viens du fait qu'un code du type n'est pas l'instanciation d'une variable mais la d�finition d'une fonction. C'est �quivalent �c'est � dire que �a d�fini une fonction a qui retourne un objet de type A et qui prend un objet de type B nomm� c.

  15. #15
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    Citation Envoy� par Sylvain Togni
    L'erreur viens du fait qu'un code du type n'est pas l'instanciation d'une variable mais la d�finition d'une fonction. C'est �quivalent �c'est � dire que �a d�fini une fonction a qui retourne un objet de type A et qui prend un objet de type B nomm� c.
    ah bon ? j'ai bien fait de poser la question j'en apprends des tonnes.. ou alors tout le monde me dis n'importe quoi.
    je savais pas que l'on pouvait d�clarer une fonction comme cela:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
        Dum dum( string(argv[1]) );
    le nom du param�tre serait donc argv[1] de type string ??!

  16. #16
    Membre �m�rite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par d�faut
    Presque, le param�tre est argv, de type string[1].

  17. #17
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    on peut d�clarer une fonction dans le corps du main() ?

  18. #18
    Membre �prouv�
    Inscrit en
    Mai 2007
    Messages
    157
    D�tails du profil
    Informations personnelles :
    �ge : 43

    Informations forums :
    Inscription : Mai 2007
    Messages : 157
    Par d�faut
    Il n'y a pas de declaration de fonction mais un appel a une fonction

  19. #19
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    D�tails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par d�faut
    Salut,

    Oui c'est une d�claration de fonction.
    Et oui on peut d�clarer une fonction dans le corps d'une autre fonction, par contre je ne sais pas si �a fait vraiment partie du standard C++ ou si c'est pour la compatibilit� avec le C.

    Pour forcer le compilateur � voir �a comme un appel de fonction on peut faire :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Dum dum( (std::string( argv[1] )) );
    MAT.

  20. #20
    Membre �m�rite
    Avatar de mamelouk
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    867
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 867
    Par d�faut
    apparement dans gcc 4, on peut d�clarer un prototype de fonction dans une autre fonction

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
            int fonction(int a); // ok
    mais pas le corps de la fonction

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
        int fonction(int a){
            return ++a;
        } // pas ok

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    erreur: a function-definition is not allowed here before «{" token
    de plus, ceci :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     int a=1;
     int fonction((int(a)); // ok
    est bien un appel de fonction

    ok j'�tait aveugle mais maintenant je vois.

Discussions similaires

  1. R�ponses: 6
    Dernier message: 06/09/2009, 12h18
  2. Erreur de compilation non comprise
    Par GuiYom00 dans le forum C
    R�ponses: 8
    Dernier message: 18/02/2008, 17h12
  3. Erreur de compilation non comprise
    Par coraziari_l dans le forum Servlets/JSP
    R�ponses: 2
    Dernier message: 09/01/2008, 17h38
  4. sscanf - syntaxe qui ne compile pas
    Par xilebo dans le forum C
    R�ponses: 4
    Dernier message: 12/09/2006, 13h41
  5. [g++]Erreur de compilation non comprise
    Par GLDavid dans le forum Autres �diteurs
    R�ponses: 4
    Dernier message: 29/05/2006, 15h16

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