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 :

discordance détectée pour '_ITERATOR_DEBUG_LEVEL'


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut discordance détectée pour '_ITERATOR_DEBUG_LEVEL'
    Bonjour,

    Je développe une application A. Cette application dépend d'une librarie L compilée en mode release.
    Lorsque j'essaie de compiler A en mode debug avec NMake et cl.exe, j'obtiens l'erreur suivante :
    error LNK2038: discordance détectée pour '_ITERATOR_DEBUG_LEVEL'*: la valeur '0' ne correspond pas à la valeur '2' in main.cpp.obj
    Je ne dispose pas des sources de L. Je ne peux donc pas la recompiler en mode debug (ce qui réglerait le problème de discordance).

    Existe-t-il un moyen lancer A en mode debug ? Sous Visual Studio ? Sous Eclipse ?

    Merci par avance pour votre aide.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Etrange. C'est courant, en mode debug, de reposer sur des bibliothèques en mode release.

    Ce fil de discussion parle d'une histoire d'en-têtes précompilées...

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Merci pour ta réponse.

    Malheureusement, je ne pense pas qu'il s'agisse du même problème.
    D'après ce que j'ai compris, il manquait une directive pragma dans l'un des fichiers .cpp de l'auteur (cette même directive étant présente dans tous ses autres fichiers). Je n'ai aucune directive pragma dans mon code.
    Après quelques recherches j'ai trouvé cette page : http://daikof622.wordpress.com/2011/...-0-in-xxx-obj/. Il y est indiqué de paramétrer _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH pour désactiver la vérification de _ITERATOR_DEBUG_LEVEL, mais je ne vois pas comment paramétrer _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH.

    Une idée ?

    Merci par avance.

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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
    Points : 4 551
    Points
    4 551
    Par défaut
    Il faut le mettre en tant que symboles définis dans les propriétés du projet. Ou rajouter /D... à la ligne de commande.
    [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.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Bonjour Emmanuel et merci pour ta réponse.

    Je souhaite générer un projet Eclipse avec CMake.
    J'aimerais donc ne pas avoir à modifier les propriétés de mon projet via l'IDE.
    Je suis parvenu à rajouter le symbole _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH via le CMakeLists.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADD_DEFINITIONS(-D_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH)
    J'obtiens toujours le même type d'erreur, mais pas sur le même fichier "obj".
    Sans le symbole, le message d'erreur est :
    error LNK2038: discordance détectée pour '_ITERATOR_DEBUG_LEVEL' : la valeur '0' ne correspond pas à la valeur '2' in main.cpp.obj
    Avec le symbole, le message d'erreur est :
    error LNK2038: discordance détectée pour '_ITERATOR_DEBUG_LEVEL'*: la valeur '0' ne correspond pas à la valeur '2' in libboost_system-vc100-mt-gd-1_44.lib(error_code.obj)
    Je ne comprends pas ce qui se passe.

    Quelqu'un pourrait-il m'éclairer ?

    Merci par avance.

  6. #6
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    J'espère que tu sais bien ce que tu fais, nymformaticien, à vouloir désactiver le check sur _ITERATOR_DEBUG_LEVEL, car il est là pour te protéger.

    Mélanger des bibliothèques debug et release sous Windows avec Visual c'est le meilleur moyen de se prendre des crashs méchants.

    Un exemple concret :
    Je crée le projet "LibRelease" qui va me générer une bibliothèque statique contenant la fonction ci-dessous "fillVector". Je génère cette lib en Release.

    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
     
    #include "LibRelease.h"
    #include <iostream>
     
    std::vector<int> fillVector(std::vector<int>& v)
    {
       std::cout << "Release : std::vector<int> size = " << sizeof(std::vector<int>) << std::endl;
       std::cout << "Release : std::vector<int>::iterator size = " << sizeof(std::vector<int>::iterator) << std::endl;
       v.clear();
       v.push_back(1);
       v.push_back(2);
       v.push_back(3);
       v.push_back(4);
       return v;
    }

    Ensuite je crée un projet ProjectUsingLibRelease comme ci-dessous, qui est linké avec ma lib LibRelease.lib. Je compile ce projet en Debug. Aussi, je rajoute _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH dans mon projet car sinon j'ai cette erreur bizarre de link, "error LNK2038: discordance détectée pour '_ITERATOR_DEBUG_LEVEL" que je ne comprends pas, mais, après tout, ça ne doit pas servir à grand chose n'est-ce 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
    #include "LibRelease.h"
    #include <vector>
    #include <iostream>
    int main()
    {
       std::cout << "Debug : std::vector<int> size = " << sizeof(std::vector<int>) << std::endl;
       std::cout << "Debug : std::vector<int>::iterator size = " << sizeof(std::vector<int>::iterator) << std::endl;
       std::vector<int> v;
       std::vector<int> v2 = fillVector(v);
       for(auto it = v2.begin(), e = v2.end(); it != e; ++it)
       {
          std::cout << *it << std::endl;
       }
    }
    Résultat de l’exécution de ProjectUsingLibRelease.exe :

    Debug : std::vector<int> size = 20
    Debug : std::vector<int>::iterator size = 12
    Release : std::vector<int> size = 16
    Release : std::vector<int>::iterator size = 4
    1
    2
    3
    4

    L'appli crash : "ProjectUsingLibRelease.exe a rencontré un problème et doit fermer. Nous vous prions de nous excuser pour le désagréablement encouru."
    L'explication c'est qu'en fonction du niveau de la macro _ITERATOR_DEBUG_LEVEL les conteneurs de la STL ainsi que leur itérateurs n'ont pas la même taille, ce qui fait le passage d'argument entre l'appli en debug et la lib en release dans la fonction fillVector() fout complètement le boxon en mémoire dans la pile et fini par faire crasher l'appli.

    En résumé, la solution correcte est de compiler boost à la fois en debug et en release et de linker dans ton appli avec libboost_system-vc100-mt-gd-1_44.lib en debug et avec libboost_system-vc100-mt-1_44.lib en release.

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Bonjour Arzar, et merci pour ta réponse.

    En résumé, la solution correcte est de compiler boost à la fois en debug et en release et de linker dans ton appli avec libboost_system-vc100-mt-gd-1_44.lib en debug et avec libboost_system-vc100-mt-1_44.lib en release.
    Et si je ne dispose pas des sources de la librairie compilée en mode release, je fais comment ? Existe-il une solution ?

    Merci par avance.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par nymformaticien Voir le message
    Bonjour Arzar, et merci pour ta réponse.



    Et si je ne dispose pas des sources de la librairie compilée en mode release, je fais comment ? Existe-il une solution ?

    Merci par avance.
    Les sources de boost, tu peux les trouver très facilement sur le site qui y est dédié ...

    Le problème release Vs debug n'est absolument pas lié aux sources (ce sont les mêmes ) mais "simplement" aux symboles éventuellement définis (ou non) au moment de la compilation (EDIT et qui doivent être les memes lorsque l'on "utilise" quelque chose qui a été compilé)

    Ce sont donc toujours les même fichiers d'en-tête que tu utilises, tu n'a que pour les bibliothèques (libboost_XXX.lib et boost_XXX.dll) dont le nom change et prend un un "d" pour "debug".

    Pour résoudre ton problème, tu n'as effectivement pas d'autre choix que de ... modifier le projet (ou du moins la cible du projet concerné) pour rajouter le symbole préprocesseur qui permettra d'éviter l'erreur à laquelle tu es confronté

    Ceci dit, tous les systèmes d'automatisation de compilation que je connais permettent de distinguer très facilement la version debug de la version release, et donc de fournir, comme c'est nécessaire ici, les symboles adaptés
    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
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Bonjour koala01, et merci pour ta réponse.

    Je ré-explique ma situation :

    Je développe une application A. Cette application dépend d'une librarie L non open source compilée en mode release. L n'est pas boost. Je ne dispose pas des sources de L.
    Je souhaite compiler A en mode debug avec NMake et cl.exe
    Est-ce possible ? Si oui, comment ?

    Merci par avance.

  10. #10
    screetch
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define _SECURE_SCL 0
    #define _HAS_ITERATOR_DEBUGGING 0
    ou mets les dans ton CMakeLists.txt

  11. #11
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Bonjour screetch et merci pour ta réponse.

    Lorsque je mets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SET(CMAKE_BUILD_TYPE "Debug")
    ADD_DEFINITIONS(-D_SECURE_SCL=0)
    ADD_DEFINITIONS(-D_HAS_ITERATOR_DEBUGGING=0)
    dans mon CMakeLists.txt, j'obtiens l'erreur suivante :
    libboost_system-vc100-mt-gd-1_44.lib(error_code.obj) : error LNK2038: discordance détectée pour '_ITERATOR_DEBUG_LEVEL'*: la valeur '2' ne correspond pas à la valeur '0' in main.cpp.obj
    Ma librairie L dépend en effet de boost.
    Apparemment, c'est bien libboost_system-vc100-mt-gd-1_44.lib qui est utilisée à l'édition de lien. Mais le symbole utilisé pour mon application reste discordant.

    Je ne comprends pas ce qui se passe.

    Merci par avance.

  12. #12
    screetch
    Invité(e)
    Par défaut
    j'ai peut être renversé les dépendances, mais ca me paraît bizarre...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define _SECURE_SCL 1
    #define _HAS_ITERATOR_DEBUGGING 1
    et avec ca?

  13. #13
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Ah ben oui forcement !

    Si tu défini :
    ADD_DEFINITIONS(-D_SECURE_SCL=0)
    ADD_DEFINITIONS(-D_HAS_ITERATOR_DEBUGGING=0)

    alors c’est très exactement identique que de définir _ITERATOR_DEBUG_LEVEL = 0

    Donc visual détecte une discordance avec boost.system en debug qui a été compilé avec les options par défaut, c'est à dire avec _ITERATOR_DEBUG_LEVEL = 2 ou alors _HAS_ITERATOR_DEBUGGING = 1 && _SECURE_SCL = 1 (c'est pareil)

    Supprime ces deux lignes, ajoute un ADD_DEFINITIONS(-D_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH) pour ne pas avoir de problème avec la lib en release et ça devrait compiler.

    Edit : Je ne connais pas bien CMake, mais sous Visual 2010, sélectionner le mode debug, définit automatiquement _ITERATOR_DEBUG_LEVEL à 2.
    Peut être que CMake ne le fait pas par défaut, et dans ce cas comme le suggère screetch il faut rajouter explicitement ADD_DEFINITIONS(-D_ITERATOR_DEBUG_LEVEL=2) pour le mode Debug dans le CMakeLists.txt

  14. #14
    screetch
    Invité(e)
    Par défaut
    ah ca y est je vois

    bon déjà oublie les deux derniers posts ils ne sont pas "à jour"
    revient a mon post, qui dit que dans ton projet tu ne dois pas avoir d'ITERATOR DEBUGGING en debug (sinon tu ne pourras pas utiliser la lib L en release)

    ensuite ca ca a reglé la moitié du problème.

    Pour etre plus clair, voila ce que tu as:

    * ton code (ITERATOR_DEBUGGING = 2)
    * la lib L en release (ITERATOR_DEBUGGING = 0)
    * boost en debug (ITERATOR_DEBUGGING = 2)

    pour faire marcher tu dois changer pour que tout ait la même valeur:

    * ton code (ITERATOR_DEBUGGING = 0) c'est ce que tu as fait grâce au premier changement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ADD_DEFINITIONS(-D_SECURE_SCL=0)
    ADD_DEFINITIONS(-D_HAS_ITERATOR_DEBUGGING=0)
    * la lib L en release (ITERATOR_DEBUGGING = 0)
    * boost en release (ITERATOR_DEBUGGING = 0) ou recompile boost sans le ITERATOR DEBUGGING (avec _SECURE_SCL 0 et _HAS_ITERATOR_DEBUGGING 0)

  15. #15
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Merci à tous.

    @screetch : en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ADD_DEFINITIONS(-D_SECURE_SCL=0)
    ADD_DEFINITIONS(-D_HAS_ITERATOR_DEBUGGING=0)
    dans mon CMakeLists.txt et en bidouillant pour que mon la librairie L link vers les librairies boost compilées en release, ça compile. Par contre,quand je souhaite debugger avec Eclipse, j'obtiens l'erreur suivante :
    gdb/mi Error stopping at main. Reason: Target requested failed: Function "main" not defined.
    De plus, les traces de gdb indique :
    Reading symbols from [...]\A.exe...(no debugging symbols found)...done.
    @Arzar : en supprimant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ADD_DEFINITIONS(-D_SECURE_SCL=0)
    ADD_DEFINITIONS(-D_HAS_ITERATOR_DEBUGGING=0)
    et en ajoutant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADD_DEFINITIONS(-D_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH)
    j'obtiens des discordances entre la librairie L et Boost.
    Rajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADD_DEFINITIONS(-D_ITERATOR_DEBUG_LEVEL=2)
    ne change rien.

    @tous : je laisse tomber. Je vais demander aux développeurs de la librairie L qu'ils me fournissent la librairie L compilée en debug.

    Encore merci pour votre aide. Ça m'a permis de comprendre plein de choses sur les mécanismes de la compilation en C++.

  16. #16
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Dois-je passer la discussion à "Résolu" ?

  17. #17
    screetch
    Invité(e)
    Par défaut
    Tu as compilé avec Visual Studio puisque ton code utilise _HAS_ITERATOR_DEBUGGING

    gdb ne peut pas debugger les modules compilés avec visual studio je crois.

    sinon ce que tu as fait avec _HAS_ITERATOR_DEBUGGING fonctionnait, mais tu vas devoir compiler avec GCC pour debugger sous GDB, ou debugger sous visual studio. Ca n'aura rien a voir avec la bibliotheque en release.

  18. #18
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 51
    Points : 26
    Points
    26
    Par défaut
    Merci pour ta réponse screetch. Ta solution était donc la bonne.

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

Discussions similaires

  1. [AS3] MC qui détecte état d'autres MC pour changer d'etat
    Par cool_yao dans le forum ActionScript 3
    Réponses: 0
    Dernier message: 08/11/2011, 22h33
  2. Réponses: 1
    Dernier message: 30/05/2008, 18h15
  3. Outils, cours et NOUVEAUX tutoriels pour Borland C++Builder
    Par hiko-seijuro dans le forum C++Builder
    Réponses: 10
    Dernier message: 12/03/2006, 22h33
  4. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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