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 :

Besoin d'aide pour contourner une internal compiler error


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut Besoin d'aide pour contourner une internal compiler error
    Bonjour à tous

    Désolé pour le titre imprécis, mais pas facile d'en trouver un pour mon problème.

    Je possède une classe abstraite, nommée ici Driver, qui sert d'interface entre le programme et des API spécifiques (chaque dérivée de Driver implémente une API différente).

    Pour des raisons diverses et justifiées, je me suis codé une petite classe proxy pour cacher les appels du genre Driver->SetSomeState(true) derrière des affectations du genre Driver->SomeState = true.

    Voici un code complet minimal qui reproduit le problème (que j'explique juste après) :

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    class Driver;
    Driver* GlobalDriver;
     
    class Driver
    {
    private :
     
        virtual void SetSomeState(bool) {}
     
    public :
     
        template <typename T, void (Driver::*Func)(T)>
        struct State
        {
            State& operator =(T Value)
            {
                (GlobalDriver->*Func)(Value);
                return *this;
            }
        };
     
        struct States
        {
            State<bool, &Driver::SetSomeState> SomeState;
        };
     
        States TheStates;
    };
     
     
    int main()
    {
        GlobalDriver = new Driver;
        GlobalDriver->TheStates.SomeState = true;
     
        return 0;
    }
    Mon problème est que ce code est valide, mais ne compile pas (Visual C++ 8 me sort une internal compiler error, suivie d'un crash du compilateur).

    J'ai isolé le problème :

    Si les fonctions de Driver ne sont pas virtuelles cela compile, mais je suis obligé de les laisser virtuelles.
    Si la classe States est définie en dehors de Driver cela compile, mais je ne peux pas non plus le faire car toutes deux sont dépendantes l'une de l'autre.
    Je pourrais également intercaler une fonction non virtuelle entre ma classe State et l'appel à la fonction virtuelle, mais c'est exclu car je dois quoiqu'il arrive être certain qu'en mode release mon mécanisme de proxy ne laisse pas de trace (ie. soit équivalent à l'appel direct).

    J'ai trituré le code dans tous les sens, mais sans jamais réussir à le faire compiler tout en gardant des fonctionnalités identiques.

    Une idée ??


  2. #2
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    avec ton code, avec g++, j'ai :

    laurent.cpp: In member function `Driver::State<T, Func>& Driver::State<T, Func>::operator=(T)':
    laurent.cpp:17: error: `GlobalA' was not declared in this scope
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                (GlobalA->*Func)(Value);
    GlobalA correspond à quoi ?
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Oups, un vieux truc qui trainait. Il fallait lire GlobalDriver.

  4. #4
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Bon, c'est définitif... change de compilateur tout simplement

    j'ai testé avec G++ sous nunux et Mingw (Dev-C++) sous Windows, et il n'y a pas de problèmes...

    il doit bien y avoir une config sous VC++ pour spécifier le compilo non ?
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Le problème est que mon code doit supporter Visual C++ (et j'imagine que si le 8 ne passe pas, les autres non plus).

    Bon, c'est tout de même rassurant de voir que gcc fait correctement son boulot.

  6. #6
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par Laurent Gomila
    Le problème est que mon code doit supporter Visual C++ (et j'imagine que si le 8 ne passe pas, les autres non plus).

    Bon, c'est tout de même rassurant de voir que gcc fait correctement son boulot.
    Bon, j'ai lu et relu les passages de ma n1905 qui concernent l'opérateur de prise d'adresse, notamment sur les fonctions membres virtuelles, et je n'ai rien vu dedans qui pourrait empêcher de faire ce que tu fais. Le problème du compilo vient peux-être du fait qu'il ne sait pas récupérer &Driver::SetSomeState à l'instanciation du template State<bool, &Driver::SetSomeState> qui est faite quand Driver n'est pas encore complètement défini (à la définition de la structure States) . Mais là, il faut attendre l'avis d'experts du langage our se prononcer en faveur d'un bug MS ou pas, car prise d'adresse de fonction membre virtuelle pendant instanciation de classe template englobée =>

    En attendant, j'ai trouvé une solution pour compiler selon tes exigences : j'ai encapsulé la fonction virtuelle, dans une structure qui est complètement définie au moment de l'instanciation du template.

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    class Driver;
    Driver* GlobalDriver;
     
    class Driver
    {
    private :
     
        struct Job{
            virtual void SetSomeState(bool) {}
            virtual void SetAnotherState(bool) {}
        } jopic;
     
    public :
     
        template <typename T, void (Driver::Job::*Func)(T)>
        struct State
        {
            State& operator =(T Value)
            {
                (GlobalDriver->jopic.*Func)(Value);
                return *this;
            }
        };
     
        struct States
        {
            State<bool, &Driver::Job::SetSomeState> SomeState;
            State<bool, &Driver::Job::SetAnotherState> AnotherState;
        };
     
        States TheStates;
    };
     
     
    int main()
    {
        GlobalDriver = new Driver;
        GlobalDriver->TheStates.SomeState = true;
        GlobalDriver->TheStates.AnotherState = false;
        return 0;
    }
    A+

Discussions similaires

  1. [VBA-E]besoin d'aide pour faire une boucle
    Par mikazounette dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 10/04/2006, 14h04
  2. besoin d 'aide pour formuler une requête
    Par cdu dans le forum Langage SQL
    Réponses: 2
    Dernier message: 08/04/2006, 19h38
  3. besoin d'aide pour optimiser une requête
    Par jisse dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/01/2006, 09h41
  4. Besoin d'aide pour afficher une image dans un applet
    Par argon dans le forum AWT/Swing
    Réponses: 16
    Dernier message: 19/01/2006, 19h45
  5. besoin d'aide pour intégrer une entité dans un MCD
    Par barkleyfr dans le forum Schéma
    Réponses: 17
    Dernier message: 13/10/2005, 13h29

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