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 :

crash �trange: bug g++?


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre �clair�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    836
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 836
    Par d�faut crash �trange: bug g++?
    J'ai un bout de code (pondu lors d'exp�rimentations) qui r�agit de fa�on assez �trange et je me demande o� est l'erreur.

    Voici le bout de code incrimin�:
    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
     
    #include <string>
    #include <stdio.h>
     
    int main(void)
    {
    	std::string test("test test");
    	std::string::iterator t1(test.begin());++t1;
    	std::string::iterator t2(t1);++t2;++t2;
    	std::string::iterator t3(test.end());t3--;
    	printf("%s:: %c %c %c\r\n",test.c_str(),*t1,*t2,*t3);
    	test.insert(t2,'!');
    	printf("%s:: %c %c %c\r\n",test.c_str(),*t1,*t2,*t3);
    	test.insert(t2,'!');
    	printf("%s:: %c %c %c\r\n",test.c_str(),*t1,*t2,*t3);
    	printf("wow\n");
    	return -1;
    }
    Le r�sultat donne:
    test test:: e t t
    tes!t test:: e t t
    :: e ! s
    wow
    *** glibc detected *** ./a.out: double free or corruption (!prev): 0x00000000014b4040 ***
    ======= Backtrace: =========
    Suivent, naturellement, la bacttrace et la memory map.
    Ce qui m'intrigue, et me fait songer � un bug de g++ plut�t qu'a une b�tise de ma part (qui est, certes, �galement possible vu que j'ai un doute quant au fait de jouer comme �a avec les it�rateurs) c'est que test.c_str() renvoie une cha�ne nulle?
    Le fait qu'il semble y avoir un double free n'est pas non plus �tranger � ma pens�e que j'aie pu d�couvrir un bug.

    Donc, si quelqu'un peut tester avec un compilo diff�rent et/ou expliquer que c'est normal (et le pourquoi du comment tant qu'a faire) je suis preneur.

    Ah, oui, "$g++ -v" me donne:
    Citation Envoy� par g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.7.2 (Debian 4.7.2-4)
    PS: oui, je sais, printf c'est pas bien pour le C++ et blablabla... mais moi j'aime pas les flux, parce que je n'aime pas taper un code super long pour rien, et en plus pour moi, les op�rateurs << et >> servent au d�calage de donn�es, pas � envoyer des donn�es dans un objet compl�tement diff�rent (pour �a y'a "operator+=" avec op�rateurs de cast et constructeurs surcharg�s... mais l� n'est pas le sujet)

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2012
    Messages
    788
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2012
    Messages : 788
    Par d�faut
    Il est possible que le string::insert invalide les it�rateurs (� confirmer).

    PS:
    Les flux, avec la surchage des op�rateurs << et >>, te permettent d'avoir:
    - une s�curit� sur le type
    - la possibilit� d'ajouter ses propres types
    Ce qui n'est pas offert (nativement) avec printf de C.
    Tu peux �crire une version de printf "correcte" en C++11 avec les variadic template.
    (Une fois de plus, C++ est typ� (contrairement au C).)

  3. #3
    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,

    Effectivement, insert va invalider tous les it�rateurs.

    Ceux de "derri�re", tr�s certainement, car il faut bien faire de la place pour caser le caract�re qu'on ajoute, mais parfois aussi les autres, car une std::string est bien souvent repr�sent�e en interne comme un tableau de caract�res contigus.

    Si, pour arriver � ins�rer le caract�re, il a fallut agrandir la taille de ce tableau, tous tes it�rateurs seront bons � jeter � la poubelle car le tableau ne se trouvera plus � l'adresse r�f�renc�e par tes it�rateurs

    A partir de l�, bah, ben on passe dans la quatri�me dimension, parce que tout ce qu'on peut dire, c'est que nous aurons un comportement ind�fini (undefined behaviour), et, comme le dit si bien le terme, nul ne peut pr�dire ce qui se passera

    Tu as d�j� de la chance de ne pas avoir provoqu� une guerre atomique
    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

  4. #4
    Membre �clair�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    836
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 836
    Par d�faut
    Citation Envoy� par koala01 Voir le message
    Salut,

    Effectivement, insert va invalider tous les it�rateurs.

    Ceux de "derri�re", tr�s certainement, car il faut bien faire de la place pour caser le caract�re qu'on ajoute, mais parfois aussi les autres, car une std::string est bien souvent repr�sent�e en interne comme un tableau de caract�res contigus.

    Si, pour arriver � ins�rer le caract�re, il a fallut agrandir la taille de ce tableau, tous tes it�rateurs seront bons � jeter � la poubelle car le tableau ne se trouvera plus � l'adresse r�f�renc�e par tes it�rateurs

    A partir de l�, bah, ben on passe dans la quatri�me dimension, parce que tout ce qu'on peut dire, c'est que nous aurons un comportement ind�fini (undefined behaviour), et, comme le dit si bien le terme, nul ne peut pr�dire ce qui se passera

    Tu as d�j� de la chance de ne pas avoir provoqu� une guerre atomique
    Merci pour les explications, je m'en doutait d'ailleurs un peu (sinon, je ne me serais pas amus� � faire un bout de code pour v�rifier la validit� jusqu'a ce que �a p�te . A noter que la premi�re insertion ne posais aucun souci avec g++ d'ailleurs.).
    Ce qui m'intrigue le plus, ce n'est pas le fait que les it�rateurs se soient auto-pourris, mais le retour de c_str() qui deviens subitement nul?
    Ce serait caus� par l'invalidation des it�rateurs?

    Pour le coup, j'imagine qu'il va falloir que je trouve le moyen de faire utiliser un autre conteneur que le vector � basic_string, mais je devrais m'en sortir.


    Hors sujet:
    Citation Envoy� par Ehonn Voir le message
    PS:
    Les flux, avec la surchage des op�rateurs << et >>, te permettent d'avoir:
    - une s�curit� sur le type
    - la possibilit� d'ajouter ses propres types
    Ce qui n'est pas offert (nativement) avec printf de C.
    Tu peux �crire une version de printf "correcte" en C++11 avec les variadic template.
    (Une fois de plus, C++ est typ� (contrairement au C).)
    Juste parce que je ne peux pas m'emp�cher, et puis, le vendredi, c'est permis:
    - une s�curit� sur le type => mou�... mais en fait, j'ai encore jamais eu de soucis de type avec un printf. P'tet parce que je ne m'en sers que pour afficher des cha�nes de caract�res et des entiers?
    - la possibilit� d'ajouter ses propres types => rien ne m'emp�che d'ajouter un op�rateur de cast vers char*
    - les flux ne permettent pas un formatage ais� et lisible, par exemple, dans les printf utilis�s, �a aurait donn� std::cout << test << ":: " << *t1 << " " << *t2 << " " << *t3 << std::endl; au lieu de printf("%s:: %c %c %c\r\n",test.c_str(),*t1,*t2,*t3);. Lequel est le plus lisible?

    De mani�re g�n�rale, le contr�le de ce qui � �t� lu/�crit est tout de m�me plus fin avec les printf/scanf (notamment scanf qui permet l'usage de regex, entres autres). Cela dis, les flux ont des avantages �galement: le support de std::string, qui permet d'�viter de ne pas avoir besoin de conna�tre la taille de l'�l�ment recevant une �criture.
    Pour finir sur cette parenth�se: les deux ont leurs avantages, et si je pense que cin/cout remplacent avantageusement certains trucs du C, il s'agit de puts et gets. printf/scanf ont un r�le tr�s diff�rent du simple affichage: l'affichage format�, avec contr�le et tol�rance d'erreur fins.

    Le C est typ�, juste plus faiblement que le C++ (vu qu'en C on peut caster � l'arrache, contrairement au C++ qui... permet de le faire d'ailleurs, via reinterpret_cast<>() le honni mais parfois n�cessaire ).

    Fin de la parenth�se hors sujet

  5. #5
    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 Freem Voir le message
    Merci pour les explications, je m'en doutait d'ailleurs un peu (sinon, je ne me serais pas amus� � faire un bout de code pour v�rifier la validit� jusqu'a ce que �a p�te . A noter que la premi�re insertion ne posais aucun souci avec g++ d'ailleurs.).
    Ce qui m'intrigue le plus, ce n'est pas le fait que les it�rateurs se soient auto-pourris, mais le retour de c_str() qui deviens subitement nul?
    Ce serait caus� par l'invalidation des it�rateurs?
    Il faut savoir que l'augmentation d'espace dans le tableau utilis� en interne par la classe string (tout comme c'est le cas pour la classe vector d'ailleurs) est faite de mani�re amortie : � chaque fois que l'on doit augmenter la taille du tableau, on l'augmente de � peu pr�s la moiti� de sa taille originale.

    Cela permet d'�viter d'avoir � augmenter la taille du tableau � chaque insertion, et donc de gagner en terme de performances (en fait, le gain sera d'autant plus grand que le tableau sera gros )

    Il peut donc arriver que les it�rateurs sur les �l�ments qui pr�c�dent l'endroit d'insertion ne soient pas invalid�s SI (et seulement si) "on a la chance" que l'insertion n'ait pas provoqu� d'�largissement du tableau

    Mais comme il est plutot difficile de d�terminer � quel moment le tableau sera �largi, et � quel moment il ne le sera pas (note qu'il y a moyen de le faire ), il est beaucoup plus sage de consid�rer que les it�rateurs sont d'office invalid�s lors de l'insertion (ou lors de la suppression, car le principe est fonci�rement le m�me, si ce n'est que l'on assiste � un "amaigrissement" du tableau utilis� en interne )
    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

  6. #6
    Membre �clair�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    836
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 836
    Par d�faut
    Citation Envoy� par Freem Voir le message
    Merci pour les explications, je m'en doutait d'ailleurs un peu (sinon, je ne me serais pas amus� � faire un bout de code pour v�rifier la validit� jusqu'a ce que �a p�te . A noter que la premi�re insertion ne posais aucun souci avec g++ d'ailleurs.).
    Ce qui m'intrigue le plus, ce n'est pas le fait que les it�rateurs se soient auto-pourris, mais le retour de c_str() qui deviens subitement nul?
    Ce serait caus� par l'invalidation des it�rateurs?
    Pour vector et string, c'est �vident, �a permet d'�viter les r�allocations � chaque fois que l'on ajoute/supprime un caract�re, et donc un gain de performances non n�gligeable en vitesse.
    Mais tout cela ne me semble pas expliquer pourquoi, et comment:
    _ test.c_str() qui est cens� renvoyer un pointeur volatile (dans le sens, pas stable, � ne pas �crire, � ne pas r�utiliser...) sur la cha�ne de caract�re brute renvoie subitement une cha�ne vide ""
    _ le crash de l'appli enti�re

    Au del� de la validit� des it�rateurs, ce sont ces points qui m'intrigue.

  7. #7
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2012
    Messages
    788
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2012
    Messages : 788
    Par d�faut
    HS:

    Je comptais pas r�pondre, mais comme il y a des questions (et qu'on est vendredi) ^^

    Citation Envoy� par Freem Voir le message
    - une s�curit� sur le type => mou�... mais en fait, j'ai encore jamais eu de soucis de type avec un printf. P'tet parce que je ne m'en sers que pour afficher des cha�nes de caract�res et des entiers?
    Parce que tu es bon
    Il me semble que gcc fait un warning si on se trompe. Mais il ne faut surtout inverser %d et %s (!)

    Citation Envoy� par Freem Voir le message
    - la possibilit� d'ajouter ses propres types => rien ne m'emp�che d'ajouter un op�rateur de cast vers char*
    (Je ne crois pas que cela existe en C) (En C++, on pr�f�rera utiliser std::string)
    (Si la classe ne t'appartient pas, tu ne peux pas ajouter un tel op�rateur toi-m�me.)

    Citation Envoy� par Freem Voir le message
    - les flux ne permettent pas un formatage ais� et lisible, par exemple, dans les printf utilis�s, �a aurait donn� std::cout << test << ":: " << *t1 << " " << *t2 << " " << *t3 << std::endl; au lieu de printf("%s:: %c %c %c\r\n",test.c_str(),*t1,*t2,*t3);. Lequel est le plus lisible?
    (Question de go�t ) (Le std::endl de C++ est une bonne chose)
    Avec printf tu es oblig� de compter les % et les arguments si tu veux en ins�rer au milieu. C'est une source d'erreur trop grande pour moi :s

    Citation Envoy� par Freem Voir le message
    Pour finir sur cette parenth�se: les deux ont leurs avantages, et si je pense que cin/cout remplacent avantageusement certains trucs du C, il s'agit de puts et gets. printf/scanf ont un r�le tr�s diff�rent du simple affichage: l'affichage format�, avec contr�le et tol�rance d'erreur fins.
    Les iostreams ont les manipulators (et autres).

    Citation Envoy� par Freem Voir le message
    Le C est typ�, juste plus faiblement que le C++ (vu qu'en C on peut caster � l'arrache, contrairement au C++ qui... permet de le faire d'ailleurs, via reinterpret_cast<>() le honni mais parfois n�cessaire ).
    Oui, faiblement typ� est plus exact. (cast implicites et pas toujours de d�tection d'erreur des types)

    Je ne pr�tends pas que les flux sont toujours meilleurs que printf et scanf et cie (quoique ^^).
    Mais il sont plus s�rs et plus simple dans la majorit� des cas

  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
    Citation Envoy� par Ehonn Voir le message
    (Question de go�t ) (Le std::endl de C++ est une bonne chose)
    Avec printf tu es oblig� de compter les % et les arguments si tu veux en ins�rer au milieu. C'est une source d'erreur trop grande pour moi :s
    A vrai dire, je crois que j'utiliserais cout, mais que je mettrais surtout le code un peu plus en forme.

    Quelque chose comme
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    std::cout << test << ":: " 
              << *t1 << " " 
              << *t2 << " " 
              << *t3 << std::endl;
    Cela ne change rien, mais au moins, il suffit de compter les lignes pour savoir si on a bien affich� tout ce qu'il nous fallait

    Tu me diras que tu peux faire pareil avec printf pour ce qui en est des variables que tu transmets, mais, pour ce qui en est de la chaine de formattage et des %...

    Imagine un peu un printf proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    printf("%s %d %f %s %d %d %d %d %u",/* heu, j'ai combien de paramètres là ??? */ );
    Faut s'user les yeux pour arriver � compter
    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
    Membre �clair�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    D�cembre 2008
    Messages
    836
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : D�cembre 2008
    Messages : 836
    Par d�faut
    Citation Envoy� par Ehonn Voir le message
    HS:
    Parce que tu es bon
    Il me semble que gcc fait un warning si on se trompe. Mais il ne faut surtout inverser %d et %s (!)
    Le jour ou je me consid�rerais bon � nouveau signifieras que j'aurai retrouv� mon niveau d'il y a 10 ans: faible

    C'est amusant de voir que quand on apprend, on apprend surtout qu'il en reste beaucoup � apprendre. C'est ce qui fait que C++ m'amuse autant, je pense. (Et puis, franchement, je me poserais toujours la question de pourquoi les langages comme java et c# conservent le new, alors qu'il n'y a pas de delete, entres autres )

    (Je ne crois pas que cela existe en C) (En C++, on pr�f�rera utiliser std::string)
    (Si la classe ne t'appartient pas, tu ne peux pas ajouter un tel op�rateur toi-m�me.)
    Pas en C, non. Pour �a que j'utilise C++

    Et si la classe ne t'appartiens pas, il me semble que la syntaxe suivante doit �tre possible (� v�rifier):
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    operator NouveauType (AncienType);
    (Question de go�t ) (Le std::endl de C++ est une bonne chose)
    Avec printf tu es oblig� de compter les % et les arguments si tu veux en ins�rer au milieu. C'est une source d'erreur trop grande pour moi :s
    Les iostreams ont les manipulators (et autres).
    Conna�t pas.

    Oui, faiblement typ� est plus exact. (cast implicites et pas toujours de d�tection d'erreur des types)
    C++ permet �galement les cast implicites, si un op�rateur adapt� existe (comme pour le C, d'une certaine fa�on: caster implicitement un float en int fonctionne, de m�moire, avec juste un warning).
    La preuve: std::string str;str+= "hello"; compile.

    Les cast implicites ne sont pas le mal, ils r�duisent le nombre de lignes de code et le rendent plus clair, intuitif. Il faut juste faire attention � ne pas d�finir de surcharge d'op�rateur non intuitive. Ce qui est, � mon avis (qui n'est pas unique, � en juger l'article fran�ais de wikipedia) le cas de l'op�rateur de d�calage de bits surcharg� en flux.

    Mais il sont plus s�rs et plus simple dans la majorit� des cas
    Je suis d'accord, ils ont chacun leurs r�les, et si le C++ consid�re le C et sa lib standard comme une partie de lui-m�me, c'est qu'il y a une raison, je pense.

    Citation Envoy� par koala01 Voir le message
    A vrai dire, je crois que j'utiliserais cout, mais que je mettrais surtout le code un peu plus en forme.

    Quelque chose comme
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    std::cout << test << ":: " 
              << *t1 << " " 
              << *t2 << " " 
              << *t3 << std::endl;
    Cela ne change rien, mais au moins, il suffit de compter les lignes pour savoir si on a bien affich� tout ce qu'il nous fallait

    Tu me diras que tu peux faire pareil avec printf pour ce qui en est des variables que tu transmets, mais, pour ce qui en est de la chaine de formattage et des %...

    Imagine un peu un printf proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    printf("%s %d %f %s %d %d %d %d %u",/* heu, j'ai combien de paramètres là ??? */ );
    Faut s'user les yeux pour arriver � compter
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    printf("%s::\
    %c \
    %c \
    %c \n",
    test, *t1,*t2);
    C'est moche, mais �a marche

    Citation Envoy� par Bousk Voir le message
    Je ne suis pas s�r que le reinterpret_cast soit le seul cas du cast en C.
    En C++ on a 3 cast, et les cast "� l'arrache" du C sont plus proches d'un static_cast il me semble.
    Le reinterpret_cast n'est en tous cas pas honni ni honteux, il a son utilit�, et c'est pour ma part celui que j'utilise au quotidien au boulot.
    4 cast, en C++.
    _ static_cast
    _ dynamic_cast
    _ reinterpret_cast
    _ const_cast
    Et si tu utilises le reinterpret_cast tout le temps, ne viens pas me parler de type safety

    Les 2 cast C++ � �viter au maximum, mais qui ont leur r�le, sont le const_cast et reinterpret_cast. Le dynamic_cast fait quelques v�rifications � la compilation et le reste � l'ex�cution (renvoie un pointeur nul ou une exception si le typage n'est pas compatible) et consomme donc du temps d'ex�cution. Le static_cast lui fait toutes les v�rifications � la compilation, et assure donc un typage fort gratuit en terme de performances.

    Mais on ne peut pas l'utiliser tout le temps: il impose l'existence d'op�rateurs de cast, qui sont souvent manquant dans la lib standard.


    Pour en revenir au sujet, j'ai constat� hier que, contrairement aux stack, queue et priority_stack, string ne permet pas de changer le conteneur sous-jacent: c'est vector ou rien.
    Il va donc me falloir r�-impl�menter std::string sur une base de std::list, de sorte que l'insertion ne devrait plus poser de probl�mes je pense. Naturellement, la suppression risque d'�tre nettement plus hasardeuse...
    A moins que quelqu'un ait une meilleure id�e?

    Ah oui, j'oubliais, le but.
    Je suppose que tout le monde conna�t scintilla et la possibilit� assez limit�e (pas de sauts de lignes, par exemple, ni de copier/coller) d'ins�rer du texte � plusieurs endroits � la fois. C'est un peu ce que je cherche � faire, un buffer permettant ce genre de manipulation, d'o� la tentative foireuse


    [edit]
    Ah, non, la syntaxe ne marche pas: doit �tre un membre non static.
    Reste la strat�gie de cr�er une classe qui � un constructeur qui prend en param�tre AncienType et poss�de un op�rateur de cast vers NouveauType:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    class Proxy
    {
    public:
      Proxy(AncienType const&);
      operator NouveauType(void)const;
    };
    Ainsi que la strat�gie d'h�ritage/surcharge:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    class Proxy: public AncienType
    {
    public:
      operator NouveauType(void)const;
    };
    Ou, tout b�tement, ajouter le constructeur n�cessaire dans la classe de destination (si on la poss�de).

    Bref, je crois que les solutions ne manquent pas

  10. #10
    R�dacteur/Mod�rateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : Canada

    Informations professionnelles :
    Activit� : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par d�faut
    Citation Envoy� par Freem Voir le message
    Le C est typ�, juste plus faiblement que le C++ (vu qu'en C on peut caster � l'arrache, contrairement au C++ qui... permet de le faire d'ailleurs, via reinterpret_cast<>() le honni mais parfois n�cessaire ).
    Je ne suis pas s�r que le reinterpret_cast soit le seul cas du cast en C.
    En C++ on a 3 cast, et les cast "� l'arrache" du C sont plus proches d'un static_cast il me semble.
    Le reinterpret_cast n'est en tous cas pas honni ni honteux, il a son utilit�, et c'est pour ma part celui que j'utilise au quotidien au boulot.
    Pensez � consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation r�seau ?
    Aucune aide via MP ne sera dispens�e. Merci d'utiliser les forums pr�vus � cet effet.

  11. #11
    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 Bousk Voir le message
    Je ne suis pas s�r que le reinterpret_cast soit le seul cas du cast en C.
    En C++ on a 3 cast, et les cast "� l'arrache" du C sont plus proches d'un static_cast il me semble.
    Le reinterpret_cast n'est en tous cas pas honni ni honteux, il a son utilit�, et c'est pour ma part celui que j'utilise au quotidien au boulot.
    Humm... Non...

    Le reinterpret_cast est bel et bien beaucoup plus proche du cast "� l'arrache" que l'on a en C que le static_cast...
    Si tu tentes le code suivant
    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
    struct A
    {
    };
    struct B : public A
    {
    };
    struct C
    {
     
    };
    int main()
    {
        A * a = new A;
        B* realB = static_cast<B*>(a); // accepté :types compatibles à la
                                       // compilation, mais crash au runtime si on essaye
                                       // d'accéder au contenu de realB 
       // C* maybeC = static_cast<C*>(a);// refusé :
       //                                // invalid static_cast from type 'A*' to 
                                         // type 'C*'
        C * hugglyC = reinterpret_cast<C*>(a); // accepté : tu sais ce que tu fais
                                               // mais crash au runtime si on essaye
                                               // d'accéder au contenu de hugglyC 
       C * cCast = (C*)a; //cast C style... oupsss
        delete a;
        return 0;
    }
    il compile tr�s bien, tant que le d�but de la ligne 16 reste comment�.

    Si tu d� commentes le d�but de la ligne C pour permettre la d�claration de maybeC, tu auras l'erreur indiqu�e

    Tant � la compilation qu'� l'ex�cution, le transtypage C style et le reinterpret_cast auront le m�me r�sultat

    La seule diff�rence entre les deux est qu'il sera plus facile de trouver les reinterpret_cast avec une commande comme grep qu'un cast C style (car (C* ) peut etre une liste d'arguments dans le prototype d'une fonction )
    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

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Crash �trange d'un QTimer
    Par esteban dans le forum Qt
    R�ponses: 9
    Dernier message: 31/10/2012, 16h48
  2. R�ponses: 6
    Dernier message: 21/08/2009, 18h20
  3. AppDomain + Generics : Crash �tranges
    Par smyley dans le forum G�n�ral Dotnet
    R�ponses: 8
    Dernier message: 05/10/2008, 21h38
  4. R�ponses: 32
    Dernier message: 21/08/2008, 12h27
  5. Tr�s �trange.. Bug impression etat
    Par Invit� dans le forum Access
    R�ponses: 2
    Dernier message: 01/08/2006, 11h44

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