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

Discussion :

Comportement bizarre de qDebug

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Par défaut Comportement bizarre de qDebug
    Bonjour à tous,
    Déjà je suis nouveau sur ce forum donc voilà, inutile de me souhaiter la bienvenue je suis ici pour travailler!
    Je vais pas passer par 4 chemins pour vous expliquer mon problème.
    J'ai créé un programme, TVServer, et un autre, TVClient.
    Dans ces deux programmes j'ai un output console basé sur qDebug. Voilà la seule portion de code sur quoi tout tient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void output(QString s)
    {
        qDebug(s.toUtf8().constData());
    }
    Afin d'avoir les accents etc. je préfère passer par UTF-8 plutôt qu'ASCII. Mais là n'est pas mon problème.
    C e code a priori n'a rien de mauvais, il se compilait parfaitement jusqu'à aujourd'hu, où subitement, plus moyen de le compiler correectement! g++ me retourne systématiquement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /home/corentin/TVServer/common.cpp:8: error: format not a string literal and no format arguments
    Je n'ai pas plus de détails que ça...
    J'ai donc essayé de bidouiller un peu mon code pour donner ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void output(QString s)
    {
        const char* data = s.toUtf8().constData();
        qDebug(data);
    }
    Mais bien évidemment, ce n'est pas en passant par une variable que ça fonctionne mieux.
    Vous allez me dire, qDebug attend un const char*. Il l'a son pu**** de const char*!
    Pourquoi il m'emmerde et refuse de compiler?
    Je ne comlprends pas comment qDebug accepte une première fois un truc, et rejette ce même truc une seconde plus tard!
    Question : Comment faire pour utiliser correctement qDebug? Ou alors avoir un truc style printf mais surtout ne jamais utiliser un truc du style
    ?
    (edit : Je ne veux pas de ce code car il me produit un truc en console très bizarre quand la phrase est longue... Et ça m'intéresse pas du tout du tout)
    Merci par avance de vos réponses
    Cocodidou

  2. #2
    Invité
    Invité(e)
    Par défaut
    D'après la doc de Qt, je vois plusieurs point à souligner. Tout d'abord l'encodage de la chaine de format :
    The format should be a Latin-1 string
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* data = s.toUtf8().constData();
    Ce code est très mauvais, dans le sens où la données renvoyées par constData() dépendent durée de vie de l'objet retourné par toUtf8(), qui est lui même détruit dès la fin de la ligne. D'après ce qui est indiqué dans les exemples qDebug() pourrait etre utilisé comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    QByteArray data = s.toUtf8();
    qDebug("%s", data.constData());
    qDebug("%s", s.toUtf8.constData());
    qDebug("%s", qPrintable(s));

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Cocodidou Voir le message
    Bonjour à tous,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /home/corentin/TVServer/common.cpp:8: error: format not a string literal and no format arguments
    Je n'ai pas plus de détails que ça...
    Et ça ne suffit pas, comme détails ? Est-ce que le paramètre est une chaine litérale ? Non. Une chaine litérale est une constante qui a la forme suivante : "....".

    Citation Envoyé par Cocodidou Voir le message
    J'ai donc essayé de bidouiller un peu mon code pour donner ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void output(QString s)
    {
        const char* data = s.toUtf8().constData();
        qDebug(data);
    }
    Mais bien évidemment, ce n'est pas en passant par une variable que ça fonctionne mieux.

    Vous allez me dire, qDebug attend un const char*. Il l'a son pu**** de const char*!
    Ou a tu vu que le compilateur te demandait un const char* ? Il te demande une pu**** de chaine literale. Et il ne l'a pas.

    Citation Envoyé par Cocodidou Voir le message
    Pourquoi il m'emmerde et refuse de compiler?
    Parce que tu l'emmerde et que tu refuse de lui donner du code qu'il peut compiler.

    Citation Envoyé par Cocodidou Voir le message
    Je ne comlprends pas comment qDebug accepte une première fois un truc, et rejette ce même truc une seconde plus tard!
    J'ai un doute. Les compilateurs sont des animaux têtus. Ils changent rarement d'avis tant que le code n'est pas modifié. Si ça compilait à un moment, c'est que tu lui passait directement la chaine de format à afficher sous la forme "...." - et pas sous la forme d'un const char*.

    Citation Envoyé par Cocodidou Voir le message
    Question : Comment faire pour utiliser correctement qDebug? Ou alors avoir un truc style printf mais surtout ne jamais utiliser un truc du style
    ?
    Surprise : c'est obligatoire. Et c'est pareil pour printf, d'ailleurs. Ca permet au compilateur de vérifier si les arguments correspondent au moins vaguement.

    Citation Envoyé par Cocodidou Voir le message
    (edit : Je ne veux pas de ce code car il me produit un truc en console très bizarre quand la phrase est longue... Et ça m'intéresse pas du tout du tout)
    Merci par avance de vos réponses
    Cocodidou
    C'est qu'il y a un autre problème
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Par défaut
    Merci beaucoup à vous de m'avoir répondu

    Ce code est très mauvais, dans le sens où la données renvoyées par constData() dépendent durée de vie de l'objet retourné par toUtf8(), qui est lui même détruit dès la fin de la ligne. D'après ce qui est indiqué dans les exemples qDebug() pourrait etre utilisé comme ceci :
    J'ai pu le constater... J'avais un seul caractère qui s'affichait en console...

    Ou a tu vu que le compilateur te demandait un const char* ? Il te demande une pu**** de chaine literale. Et il ne l'a pas.
    Eh bien je crie victoire : Il l'a sa chaîne littérale! Il fallait compiler sans le paramètre -Wformat-security; certes c'est moins "sécurisé" car je peux lui faire rentrer n'importe quoi même une chaîne pas littérale... Cela dit vu que je lui fais rentrer un QString, ce sera nécessairement une chaîne littérale en sortie de s.toUtf8().constData().

    Surprise : c'est obligatoire. Et c'est pareil pour printf, d'ailleurs. Ca permet au compilateur de vérifier si les arguments correspondent au moins vaguement.
    Oui mais voilà, on connaît tous les problèmes du printf...

    J'ai un doute. Les compilateurs sont des animaux têtus. Ils changent rarement d'avis tant que le code n'est pas modifié. Si ça compilait à un moment, c'est que tu lui passait directement la chaine de format à afficher sous la forme "...." - et pas sous la forme d'un const char*.
    Non, jamais je ne lui ai passé sous cette forme...
    Enfin voilà, je bypasse la sécurité du compilateur pour lui écarter tout doute et ça fonctionne!

  5. #5
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Cocodidou Voir le message
    Ou a tu vu que le compilateur te demandait un const char* ? Il te demande une pu**** de chaine literale. Et il ne l'a pas.

    Eh bien je crie victoire : Il l'a sa chaîne littérale! Il fallait compiler sans le paramètre -Wformat-security; certes c'est moins "sécurisé" car je peux lui faire rentrer n'importe quoi même une chaîne pas littérale... Cela dit vu que je lui fais rentrer un QString, ce sera nécessairement une chaîne littérale en sortie de s.toUtf8().constData().
    Non. Une chaine littérale n'est pas qu'une chaine constante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const char* ceci_est_une_chaine_constante = "ceci est une chaine littérale";
    C'est la même différence qu'entre un symbole qui référence un nombre et le nombre lui même.

    Tu continue de lui donner une chaine constante, et pas une chaine littérale. Tu préfères bypasser la sécurité, c'est un choix. Ca veut dire aussi que si ta chaine en retour contient un caractère %, tu va provoquer des tas de problèmes qui seront difficiles à debugger.

    Le compilateur ne te dit pas ça pour t'embêter, mais pour te faire gagner du temps par la suite.

    Edit : si tu penses qu'utiliser les flags du compilateurs pour éviter une erreur est une bonne chose, je pense qu'il va te falloir repenser ta méthode. Pour un professionnel, c'est assez peu pardonnable. Sans compter que ce flag n'est pas nécessairement garanti pour l'avenir.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour Cocodidou et bienvenu sur le forum

    Plutôt que faire n'importe quoi avec les options de compilation, pourquoi ne pas utiliser la syntaxe suivante, comme indiqué dans la documentation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void output(QString s)
    {
        qDebug() << s;
    }
    Et d'ailleurs, pourquoi créer une fonction ouput alors que qDebug() est accessible partout ?

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Bonjour Cocodidou et bienvenu sur le forum

    Plutôt que faire n'importe quoi avec les options de compilation, pourquoi ne pas utiliser la syntaxe suivante, comme indiqué dans la documentation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void output(QString s)
    {
        qDebug() << s;
    }
    Et d'ailleurs, pourquoi créer une fonction ouput alors que qDebug() est accessible partout ?
    (Modérateurs j'ai enfin trouvé la fonction "citer" mais merci de m'avoir corrigé.
    Alors je crée cette fonction output(QString s) car comme son paramètre unique l'indique, je manipule des QString,par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QString("Received a connection from ")+QHostAddress::toString()
    Et je n'ai pas envie de systématiquement tout convertir en const char*...
    Donc du coup, j'ai préféré faire une fonction globale...
    Dur à comprendre les raisons de ce choix mais je l'ai fait quand même.
    Autre chose,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void output(QString s)
    {
        qDebug() << s;
    }
    requiert un include de QtDebug, et pour des raisons de portabilité (client portable sur une clé USB), je ne pense pas qu'il soit utile d'encombrer l'utilisateur d'une DLL de plus...
    Cela dit s'il n'y a que ça à faire je m'y résoudrai!
    Donc temporairement je me prive de console output car
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     qDebug("%s",s.toLatin1().data())
    me retourne quand la chaîne est trop longue, un caractère bizarre...
    Edit : si tu penses qu'utiliser les flags du compilateurs pour éviter une erreur est une bonne chose, je pense qu'il va te falloir repenser ta méthode. Pour un professionnel, c'est assez peu pardonnable. Sans compter que ce flag n'est pas nécessairement garanti pour l'avenir.
    Je ne suis pas professionnel mais adolescent programmant pour le fun... Donc là je force le passage. Mais j'ai prévu dans un futur plus ou moins proche de bien étudier la chose et de changer mes méthodes, très archaïques...
    edit : Corrigé un terme peu adapté à la situation

  8. #8
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Et je n'ai pas envie de m'emmerder systématiquement à tout convertir en const char*...
    Donc du coup, j'ai préféré faire une fonction globale...
    Le fait est que qDebug() est déjà une fonction "globale" et qui accepte les QString (et bien d'autres types). Donc aucun intérêt de créer une fonction "output"

    (PS : fais attention aux termes que tu utilises)

    requiert un include de QtDebug, et pour des raisons de portabilité (client portable sur une clé USB), je ne pense pas qu'il soit utile d'encombrer l'utilisateur d'une DLL de plus...
    Sauf que ton #include <QDebug>, tu le mets probablement dans ton fichier d'en-tête et donc celui ci inclura également QDebug.
    Pour ce qui est de la dll, QDebug fait partie de QtCore.dll, que tu devras fournir de toute façon (tu utilises des QString qui sont dans QtCore aussi). De plus 2 Mo, à notre époque, ce n'est rien du tout. Si tu es a 2 Mo près, n'utilise pas du tout Qt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qDebug("%s",s.toLatin1().data());
    N'utilises pas cette syntaxe mais celle ci dessous :
    En fait, remplace simplement tous tes appels à "output" par un appel à qDebug() directement.

    Dernier point : comme son nom l'indique, QDebug est sensé servir de sortie de débogage, pas de sortie standard pour une application finale.


    Bonne continuation

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 7
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Si tu es a 2 Mo près, n'utilise pas du tout Qt.
    Disons que l'espace disponible dans l'environnement où je vais l'utiliser ne dépassant guère les 10 Mo, je dois me restreindre un peu
    Citation Envoyé par gbdivers Voir le message
    Dernier point : comme son nom l'indique, QDebug est sensé servir de sortie de débogage, pas de sortie standard pour une application finale.
    Groso modo oui, ce que je lui fais sortir n'est pas destiné à l'utilisateur final, mais plutôt à indiquer à quelle instruction le programme "crashe" : je mets des output(QString) très régulièrement, ainsi je vois précisément quelle est l'instruction qui fait planter le programme... Eh oui vous me direz que je ne suis pas aguerri, mais bon quand on commence depuis 1 mois on ne gère pas ce genre de machins-là!
    Citation Envoyé par gbdivers Voir le message
    Bonne continuation
    Vous de même, bonnes fêtes, joyeux Noël et bonne année à tous et à toutes!

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Disons que l'espace disponible dans l'environnement où je vais l'utiliser ne dépassant guère les 10 Mo, je dois me restreindre un peu
    A partir du moment où tu utilses QDebug, que se soit dans une seule fonction ou dans tout ton code, ça revient au même.

    Regarde la possibilité de compiler en statique si tu est fortement limité par la place mémoire.

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

Discussions similaires

  1. Comportement bizarre de mes FPS
    Par Ekinoks dans le forum OpenGL
    Réponses: 7
    Dernier message: 22/08/2005, 15h14
  2. xsl:test .... avec comportement bizarre
    Par Blue LC dans le forum XMLRAD
    Réponses: 2
    Dernier message: 10/06/2005, 13h56
  3. [ACESS][MEMO][ISNULL]Comportement bizarre
    Par seb.49 dans le forum ASP
    Réponses: 2
    Dernier message: 09/06/2004, 10h44
  4. [HttpClient] comportement bizarre, saute des catch()...
    Par iubito dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 04/02/2004, 15h25
  5. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 10h39

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