OVH Cloud OVH Cloud

OutputDebugString style "sprintf"

46 réponses
Avatar
stat
Bonjour,

J'ai besoin d'aide pour creer une fonction de type OutputDebugString
qui envoit un message de debuggage mais qui soit aussi facile a
utiliser que printf c'est a dire que je puisse l'utiliser de la sorte

OutputDebugStringExt("Valeur x: %i, valeur y: %i, Nom: %s\n", x, y,
Nom);

et j'avoue ne pas savoir du tout comment m'y prendre

Avez-vous une idee pour commencer svp ?

Merci.

--
This is an automatic signature of MesNews.
Site : http://www.mesnews.net

10 réponses

1 2 3 4 5
Avatar
James Kanze
Sylvain wrote:
James Kanze wrote on 24/11/2006 21:44:

évidemment c'est un feature de dubug, donc tu sais que les chaines
formattées ne dépassent jamais la longueur réservée (2048 ici) ...


Jusqu'elles le font.


pardon ?


C'est que tu sais que les chaînes formattées ne dépasseront
jamais la longueur réservée, jusqu'elles le font.

C-à-d qu'en fait, tu n'en sais rien, au moins de pouvoir voir
dans la future.

Pourquoi 2048, d'ailleurs ? Pourquoi pas
2000 ? Ou 10000 ?


parce que j'ai dit "je choisis arbitrairement 2048!!!"


D'accord, mais alors, pourquoi pas 2 ? Si le choix est
réelement arbitraire, 2, c'est aussi bien 2048.

De l'autre côté, il y a toujours le problème des types qui ne
conviennent pas.


s'il n'y avait qu'un vague problème de type lorque l'on a besoin de
faire de sortie vers la "console systeme" tout irait bien!!!


Peut-être, mais pourquoi ajouter aux problèmes ?

la question n'est pas ici, est-ce que je suis capable d'écrire
toto("%d %s", 32, "heelo world")
ou au contraire suffisemment con pour mettre
toto("%d %s %i %c %f", "hello world", 25, "bouf", "pan")
mais juste de tracer (par exemple) si l'on rentre ou non dans une
fonction qui ne peut pas être tracée sous debugger symbolique.

Printf et compagnie, c'est un core dump larvé.


lorsque l'on fait exprès d'être bête, oui.


Lorsqu'on n'est pas parfait, oui. Toi, peut-être, tu es parfait
et ne fais jamais d'erreurs, mais ce n'est le cas d'aucun
programmeur que je n'ai jamais rencontré.

Comme Loïc, je ne trouve pas la syntaxe de printf
particulièrement conviviable. Mais si on y tient, il y a
boost::format.


bien sur il y a toujours des centaines de kilos de librairie pour
remplacer une primitive inutilement (dans le contexte) du CRT, ...


Une primative qui garantit un core dump à la longue, oui. Une
primative dont l'utilisation est interdite dans toutes les
règles de codage que je connais.

Il y a même une classe équivalente à mon site,
dans le répertoire Old/Text. (Je ne la maintient plus,
parce que je n'en vois pas l'utilité.)


?! moi non plus je ne verrais pas l'utilité d'une usine à gaz pour
logger des "in toto, leaving titi".


Si c'est tous ce qu'on veut, évidemment, std::cout fait très
bien l'affaire.

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
James Kanze
Sylvain wrote:
Loïc Joly wrote on 24/11/2006 23:14:

J'ai déjà vu des bugs dans du code de log écrit à la printf.


je l'ai dit, on a le droit d'être nul, stupide, incompétent, ...


Est-ce qu'on a aussi le droit d'être arrogant, prétentieux, et
faire semblant de ne jamais faire des erreurs ?

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
James Kanze
Sylvain wrote:
Loïc Joly wrote on 25/11/2006 09:38:
[] on peut partir, sur un retour std::string,
qui donne le résultat attendu.


Et n'est pas utilisable directement dans un printf...


?! parce qu'il n'a pas d'opérateurs de coercion vers const char* ?


Non, il n'y a pas d'opérateur de conversion implicite vers const
char*. Les auteurs de std::string n'étaient pas complétement
incompétant. (Les auteurs de C99 non plus, qui l'ont estîmé
nécessaire de créer un remplaçant de sprintf, parce qu'il n'y a
pas d'utilisation correcte possible de sprintf.)

Pas que la présence ou l'absence de l'un opérateur de conversion
ne change quoique ce soit.

Comme Sylvain l'a dit, « on a le droit d'être nul, stupide,
incompétent,... » Il ne fait qu'exercer ses droits.

une raison de plus (pour moi) de ne pas l'utiliser.


Mieux vaut du code incorrect, n'est-ce pas ?

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Jean-Marc Bourguet
"James Kanze" writes:

Sylvain wrote:
Loïc Joly wrote on 24/11/2006 23:14:

J'ai déjà vu des bugs dans du code de log écrit à la printf.


je l'ai dit, on a le droit d'être nul, stupide, incompétent, ...


Est-ce qu'on a aussi le droit d'être arrogant, prétentieux, et
faire semblant de ne jamais faire des erreurs ?


Ça va souvent de pair.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Sylvain
James Kanze wrote on 26/11/2006 13:27:

Non, il n'y a pas d'opérateur de conversion implicite vers const
char*. Les auteurs de std::string n'étaient pas complétement
incompétant. (Les auteurs de C99 non plus, qui l'ont estîmé
nécessaire de créer un remplaçant de sprintf, parce qu'il n'y a
pas d'utilisation correcte possible de sprintf.)


qui a parlé de la compétence des auteurs de string ou de C99 ???

oser utiliser quelque chose de différent de la production de ces auteurs
serait *par essence* irrespectueux, les dénigrer ???

gageons que ces auteurs là n'ont pas la susceptibilité aussi mal placée
que tu le prétends.

Comme Sylvain l'a dit, « on a le droit d'être nul, stupide,
incompétent,... » Il ne fait qu'exercer ses droits.


pouf, pouf, pouf !!!

"être nul" dans ma citation, c'est écrire:
toto("%d %s %i %c %f", "hello world", 25, "bouf", "pan")



essaie de citer correctement, cela évitera les insultes gratuites.

une raison de plus (pour moi) de ne pas l'utiliser.
Mieux vaut du code incorrect, n'est-ce pas ?



donc *par essence* tout ce qui est production personnelle est incorrect,
hmm, tu considères cela pour ton code aussi alors ...

Sylvain.


Avatar
James Kanze
Sylvain wrote:
James Kanze wrote on 26/11/2006 13:27:

Non, il n'y a pas d'opérateur de conversion implicite vers const
char*. Les auteurs de std::string n'étaient pas complétement
incompétant. (Les auteurs de C99 non plus, qui l'ont estîmé
nécessaire de créer un remplaçant de sprintf, parce qu'il n'y a
pas d'utilisation correcte possible de sprintf.)


qui a parlé de la compétence des auteurs de string ou de C99 ???


Tu as critiqué l'absense d'une conversion implicite dans
std::string.

Quant aux auteurs de C99, ils ont considéré que sprintf, dans sa
forme actuelle, n'était pas utilisable.

oser utiliser quelque chose de différent de la production de ces auteurs
serait *par essence* irrespectueux, les dénigrer ???


Utiliser quelque chose de différent, pourquoi pas ? Utiliser
quelque chose qu'ils ont estîmé inutilisable, en revanche...

gageons que ces auteurs là n'ont pas la susceptibilité aussi mal plac ée
que tu le prétends.

Comme Sylvain l'a dit, « on a le droit d'être nul, stupide,
incompétent,... » Il ne fait qu'exercer ses droits.


pouf, pouf, pouf !!!

"être nul" dans ma citation, c'est écrire:
toto("%d %s %i %c %f", "hello world", 25, "bouf", "pan")



essaie de citer correctement, cela évitera les insultes gratuites.


Et quelle est la différence entre ça et :

sprintf( buf, "%s", x.toString() ) ;

ou x.toString() renvoie un std::string ? Je n'en vois pas.

une raison de plus (pour moi) de ne pas l'utiliser.
Mieux vaut du code incorrect, n'est-ce pas ?



donc *par essence* tout ce qui est production personnelle est incorrect,
hmm, tu considères cela pour ton code aussi alors ...


Je trouve que passer un type comme std::string à un vararg n'est
pas correct, étant donné que la norme l'interdit, et qu'il ne
fonctionne pas avec la plupart des compilateurs.

Je trouve qu'utiliser sprintf n'est pas correct non plus. (En
fait, c'est possible à l'utiliser, mais c'est extrèmement
complexe, et il exige un buffer alloué dynamiquement, dont on a
calculé la taille en fonction du contenu de la chaîne de
formattage.)

--
James Kanze (Gabi Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Jean-Marc Bourguet
Sylvain writes:

Jean-Marc Bourguet wrote on 25/11/2006 20:42:
Passer une instance de classe à une fonction variadique,
c'est un comportement indéfini, [...]


passer des instances à printf() surement - *personne ne l'a évoqué ici*


C'est pourtant toi l'auteur de ce message auquel répondais Michel, et qui
était cité dans le message auquel tu réponds, non?

Loïc Joly wrote on 25/11/2006 09:38:
[] on peut partir, sur un retour std::string, qui donne le résultat
attendu.
Et n'est pas utilisable directement dans un printf...



?! parce qu'il n'a pas d'opérateurs de coercion vers const char* ?
une raison de plus (pour moi) de ne pas l'utiliser.

Sylvain.


J'ai du mal à l'interpréter autrement que comme sous-entendant que la
raison pour laquelle on ne peut pas passer directement un std::string à un
printf est l'absence de conversion implicite en const char*.

ailleurs, ie à une fonction variadique prévu pour, cela sera défini, par
ce que fait la fonction justement.


Tu peux m'instruire en la manière d'écrire une fonction variadique à
laquelle on peut passer une instance? Je pensais que 5.2.2/7 (If the
argument has non-POD class type, the behavior is undefined.) était assez
définitif sur ça, mais je ne connais pas la norme dans son entièreté et ai
pu manquer le paragraphe qui donne un cas où c'est possible.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Sylvain
James Kanze wrote on 26/11/2006 13:14:
Sylvain wrote:
James Kanze wrote on 24/11/2006 21:44:

évidemment c'est un feature de dubug, donc tu sais que les chaines
formattées ne dépassent jamais la longueur réservée (2048 ici)....


Jusqu'elles le font.
pardon ?

C'est que tu sais que les chaînes formattées ne dépasseront

jamais la longueur réservée, jusqu'elles le font.


faut-il lire "jusqu'à ce qu'elles le fassent" ("jusqu'à ce qu'elles
débordent les 2048") -- je ne pinaille pas la grammaire, je ne suis
simplement pas sur de comprendre ton point.

je rappelle à ton attention que j'ai utilisé "_vsnprintf" pas
"vsprintf", si les paramètres formattés dépassent les
longueur-fournie-du-buffer, la réponse est tronquée à
longueur-fournie-du-buffer caractères (point)
pas de core-dump, pas de "c'est-pas-possible-à-utiliser", juste tronqué,
donc au développeur de réfléchir 30 sec. à la taille dont il aura besoin
pour des messages clairs (non coupés).

C-à-d qu'en fait, tu n'en sais rien, au moins de pouvoir voir
dans la future.


mais on ne sait jamais rien mon bon James c'est bien connu, on devrait
d'ailleurs resté en permanence son cul stocké dans un coin et surtout ne
pas coder, on ne sait pas si les ordinateurs existeront toujours demain,
hein ?

sur un ton moins "qu'est ce qu'on s'emmerde le dimanche", quand on
développe une fonction "toto" qui formatte, par exemple
"Itération 3 : Objet = {1, 3, "Toto", true}"
on ne se demande pas si, dans le futur, on ne voudra pas mettre 2
espaces en plus - ou alors excusez-moi de ne pas participer à cette
palpitante réflexion.

Pourquoi 2048, d'ailleurs ? Pourquoi pas
2000 ? Ou 10000 ?


parce que j'ai dit "je choisis arbitrairement 2048!!!"


D'accord, mais alors, pourquoi pas 2 ? Si le choix est
réelement arbitraire, 2, c'est aussi bien 2048.


si tu le dis, 2 doit être bien.

De l'autre côté, il y a toujours le problème des types qui ne
conviennent pas.
s'il n'y avait qu'un vague problème de type lorque l'on a besoin de

faire de sortie vers la "console systeme" tout irait bien!!!
Peut-être, mais pourquoi ajouter aux problèmes ?



en clair ? parce qu'un driver, un module proche du système, plein de
code, n'ont pas à s'encombrer des librairies qui ne leur servent à rien;
par contre ils savent avec certitude que pour formatter une chaine de 5
caractères(8bit) + un espace + un int32, 18 caractères suffiront même
dans le futur -- ah c'est vrai on n'apprend plus à compter (même
l'addition) à l'école, et ce serait débile d'apprendre ça puisqu'il y a
std::trucQuiLuiSaitCompter.

Lorsqu'on n'est pas parfait, oui. Toi, peut-être, tu es parfait
et ne fais jamais d'erreurs, mais ce n'est le cas d'aucun
programmeur que je n'ai jamais rencontré.


un dimanche triste et gris ....

Une primative qui garantit un core dump à la longue, oui.


relis, "_vsnprintf" pas "vsprintf", et si _vsnprintf n'est pas portable,
je ne pense pas que OutputDebugString l'était, cela reste donc pertinent.

Une primative dont l'utilisation est interdite dans toutes les
règles de codage que je connais.


si ce sont des règles pour blaireaux c'est p.e. bien.
moi, je considère que les gens avec plus de respect pour leur interdire
des trucs -- et oublie pas d'interdire le feu (ça brule), l'électricité
(ça tue), la télé (ça, ça rend vraiment con), etc, etc.

Si c'est tous ce qu'on veut, évidemment, std::cout fait très
bien l'affaire.


quel rapport ? std::cout écrit sur le "system debugger" ??

Sylvain.




Avatar
Sylvain
James Kanze wrote on 26/11/2006 17:50:

qui a parlé de la compétence des auteurs de string ou de C99 ???


Tu as critiqué l'absense d'une conversion implicite dans
std::string.


je me cite:

?! parce qu'il n'a pas d'opérateurs de coercion vers const char* ?


si *tu* considères cette question comme un e "critique", *tu* as un
problème, pas moi.

Quant aux auteurs de C99, ils ont considéré que sprintf, dans sa
forme actuelle, n'était pas utilisable.


bis, j'ai bien lu ton point.

[...]
Et quelle est la différence entre ça et :


sprintf( buf, "%s", x.toString() ) ;

ou x.toString() renvoie un std::string ? Je n'en vois pas.


ai-je écris quelque part "sprintf(buf, "%s", std::string);" NON

je re-répète générer un output, le formatter avec d'autres trucs sont 2
étapes; je ne prétends pas moi avoir la std philosophale qui fait tout
d'un coup.

Je trouve qu'utiliser sprintf n'est pas correct non plus. (En
fait, c'est possible à l'utiliser, mais c'est extrèmement
complexe, et il exige un buffer alloué dynamiquement, dont on a
calculé la taille en fonction du contenu de la chaîne de
formattage.)


oulala calculer une taille ... dynamique en plus ... c'est vrai que ça
fait peur ça alors.

Sylvain.


Avatar
Michel Decima
Sylvain wrote:

en clair ? parce qu'un driver, un module proche du système, plein de
code, n'ont pas à s'encombrer des librairies qui ne leur servent à rien;
par contre ils savent avec certitude que pour formatter une chaine de 5
caractères(8bit) + un espace + un int32, 18 caractères suffiront même
dans le futur -- ah c'est vrai on n'apprend plus à compter (même
l'addition) à l'école, et ce serait débile d'apprendre ça puisqu'il y a
std::trucQuiLuiSaitCompter.


Ca me rappelle l'histoire d'un systeme d'exploitation dont on excuse
souvent l'instabilité récurrente par la mauvaise qualité des drivers
fournis par des vendeurs tiers. Merci de la confirmation.

1 2 3 4 5