[C++] Dynamic_cast sans RTTI ....

Dynamic_cast sans RTTI .... [C++] - Programmation

Marsh Posté le 07-03-2002 à 15:16:33    

bon voila mon problème. J'ai le code suivant :
 
class A
{
   public: virtual ~A() {}  
};
class B : public A
{
   public: virtual ~B() {}
};
class C : public B
{
   public: virtual ~C() {}
};
 
void main()
{
   A*     pA=new C;
   B*     pB;
   C*     pC;
 
   pB = dynamic_cast<B*>(pA);
   pC = dynamic_cast<C*>(pA);
}
 
Donc pour que ce code marche il faut compiler avec les RTTI. Hors en réfléchissant un peu, je me suis dit qu'il n'y avait pas besoin du RTTI pour connaitre le type d'une classe.
 
En effet, la variable pA contient un pointeur vers la table virtuelle des fonctions. Donc normalement :hap:  à l'execution, sans rajouter d'info tel que les RTTI, le programme devrait être capable de me dire si mon objet pA est "castable" en C*.
En effet il suffit qu'il regarde si le pointeur de la table de fonction virtuelle de pA est égale à la table de fct virtuelle de C (qui est toujours la même quelque soit l'instance créer normalement).  
Et pour le cast en B*, c'est pareil, il regarde la table de fct virtuelle et le programme devrait pouvoir voir que mon pA est un C* et que donc, il peut donc le caster en B*, puisque B hérite de C.
 
Donc, es-ce qu'il y a une fonction C++ qui permet de faire ce que je dis. Sachant que toutes mes classes ont des opérateurs virtuels et qu'elles ne font pas d'héritage multiple.

 

[jfdsdjhfuetppo]--Message édité par leander--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 07-03-2002 à 15:16:33   

Reply

Marsh Posté le 07-03-2002 à 15:56:24    

Encore toi :)
mais c'est affreux ca :D
 
Bon il me semble que tu as oublié les "virtual"
 
class B: virtual public A
{
};
 
Cela dit, j'ai pas trop pris la peine de lire...je m'y pencherai ce soir si j'ai le tmps ! :)


---------------
Si t'es pas net, reste a la buvette
Reply

Marsh Posté le 07-03-2002 à 16:01:10    

Parce que si tu met pas virtual quand tu dérive tes classes ben, les données de la clase mère sont recopiées dans les classes filles. D'où ambiguité et problèmes.


---------------
Si t'es pas net, reste a la buvette
Reply

Marsh Posté le 07-03-2002 à 16:05:35    

Eh oui, c'est encore moi ;)
 
Mais non, non pas de virtual avant l'héritage.
 
Je ne fais pas d'héritage multiple et je ne veux pas utiliser les RTTI.

Reply

Marsh Posté le 07-03-2002 à 16:13:06    

ça m'étonnerait qu'il y ait une fonction c++ pour tester ce genre de trucs, car le standard ne spécifie rien pour l'implémentation des méthodes virtuelles, c'est juste que tout le monde fait des vtables. maintenant, y'a peut-être des 'microsoft specific' ...  
 
mais à moins de créer une 'factory' qui s'occupe de créer les objets et d'enregister leur vtable, je vois pas bien.  
 
pourquoi tu n'implémentes pas un isKindOf() à la main ? c'est tout simple ...

Reply

Marsh Posté le 07-03-2002 à 16:15:34    

merde heu forcément sans regarder le code :)
heu ca compile pas sans les RTTI? (warning? ou error?)
(je débarque)


---------------
Si t'es pas net, reste a la buvette
Reply

Marsh Posté le 07-03-2002 à 16:17:00    

Pourquoi ne programmes-tu pas en assembleur, ainsi tu aurrais tout loisir d'acceder a la vTable !
 
Pourquoi en C il faut mettre des accolabes plutot que des begin/end ?
 
Il a des question auxquelles la seule reponse est parce que...
 
Pourquoi-faut il RTTI pour utiliser le dynamic_cast : parce que !
 
Effectivement ta methode marche... Dans le cas que tu indique
Mais il est possible d'avoir des cas ou la vTable serait la meme, par une optimisation du compilo et parce que la classe heritiere ne redefinit aucune fonction...
 
Maintenant si ta question est plutot je n'ais pas acces au RTTI (parce compilo ancien par ex), et bien oui il existe des mthodes pour emuler le dynamic_cast, ces methodes repose sur un pricinpe introdure dans les classes des attributs decrivant la classe.
 
Par exemple  
ajoute virtual A* getA();
       virtual B* getB();
       virtual C* getC();
dans A, B et C puis ces methodes retourneront NULL ou this en fonction de la classe dans laquelle elle sont implementes...
Et tu as un comportement comme dynamic_cast<>, que je n'utilise personnelement peu preferant la methode citee plus haut, qui si elle est lourde montre au lecteur du code que je me trouve dan,s le besoin de down_caster, ce qui est suffisement inhabutuel a mon sens pour que le fait soit fait explicitement au moment de conception...

Reply

Marsh Posté le 07-03-2002 à 16:20:44    

avec la stl, tu as typeid qui renvoie un type_info...
 
 
houlala oui, je suis à la masse, j'avais pas lu ton post, my mistake!!


---------------
Si t'es pas net, reste a la buvette
Reply

Marsh Posté le 07-03-2002 à 16:23:34    

- Willythekid : sans RTTI ça compile avec un warning mais à l'execution ça plante.
 
- youdontcare : c'est un isKindOf() par classe ou un isKindOf globale ? Tu pourrais me donner un chtite exemple ?

Reply

Marsh Posté le 07-03-2002 à 16:27:30    

je reste partisan du isKindOf().
 
classe de base :
 
class A
{
 virtual bool isKindOf(char* str) { return !strcmp(str, "A" ); }
};
 
puis pour les classes dérivées :
 
class B : public A
{
 virtual bool isKindOf(char* str) { return !strcmp(str, "B" ) ? true : A::isKindOf(str); }
};
 
class C : public A
{
 virtual bool isKindOf(char* str) { return !strcmp(str, "C" ) ? true : A::isKindOf(str); }
};
 
ce qui peut se ranger dans une jolie macro :D
 
PARCE QUE ! :D
 
 
donc ensuite :
 
A* obj1 = new B();
A* obj2 = new C();
 
B* b = null;
C* c = null;
 
if (obj1->isKindOf("B" )) b = (B*)obj1;
if (obj2->isKindOf("C" )) c = (C*)obj2;
 
méthode utilisée dans max, les mfc, unreal, half life, j'en passe et des meilleures.

 

[jfdsdjhfuetppo]--Message édité par youdontcare--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 07-03-2002 à 16:27:30   

Reply

Marsh Posté le 07-03-2002 à 16:43:57    

youdontcare  > chacun sa methode...  
Je prefere la mienne qui enleve le down-cast... :D
 
Parce que les down_cast c'est mal :)

Reply

Marsh Posté le 07-03-2002 à 16:46:48    

>> chacun sa methode...  
 
:jap:
 
>> Parce que les down_cast c'est mal :)  
 
ta méthode implique de changer toutes les classes dès qu'on en rajoute une. ça aussi c'est mal ;)

Reply

Marsh Posté le 07-03-2002 à 16:46:50    

merci youdontcare, c'est peu la même que je craignais. C'est vrai qu'elle est pas mal, mais elle a un petit defaut à mon gout :
En effet j'aurai aime que chaque personne codant une classe n'est pas à retaper la fonction IskindOf.
 
Tu parlais d'une macro, je suis super interessé ! Je suis fan des macros ;)
 
Es-ce que tu pourrais m'expliquer ?
 
Parce que si mon code ressemblait à ça :
class C : public A  
{  
DEFINE_IFKINDOF()
};  
 
je serais au anges ... voir même ça :
class C : public HERITAGE( A )
{  
DEFINE_IFKINDOF()
};  
 
j'accepterais ;)
 
Sinon, Benb, t'as méthode ne peut pas me convenir, parce que je rajoute des classes en nombre indéfini.

Reply

Marsh Posté le 07-03-2002 à 16:55:58    

dans un framework 'extensible', les macros sont hyper utilisées pour ce genre de trucs. dans half life (de mémoire), ça définit par ex isKindOf(), qq variables & méthodes qui s'occupent de sauvegarder la classe automatiquement, et plein d'autres trucs sympas. si tu veux te prendre une belle baffe niveau archi, choppe la sdk de half life :)  
 
pour une macro, tu as au moins deux options :
 
class C : public A  
{  
  DEFINE_ISKINDOF(C, A)  
};  
 
avec
 
#define DEFINE_ISKINDOF(C, BASE) \
        virtual bool isKindOf(char* str) { return !strcmp(str, ##C) ? true : BASE::isKindOf(str); }  
 
 
ou :
 
defineClass(C, A)
   // tes méthodes ...
endClass()
 
avec
 
#define defineClass(C, BASE) \
class C : public BASE \
{ \
  virtual bool isKindOf(char* str) { return !strcmp(str, ##C) ? true : BASE::isKindOf(str); }  
 
#define endClass };
 
//
 
le "truc magique" ici, c'est ## (ou seulement # ? me souviens plus ..) qui transforme le paramètre en string.

Reply

Marsh Posté le 07-03-2002 à 16:56:33    

on ne peut pas juste avoir
 
DEFINE_ISKINDOF()  
 
car les macros sont quand même hyper limitées :(

Reply

Marsh Posté le 07-03-2002 à 17:02:37    

ok merci pour tes macros, en effet j'avais pas penser à une macro toute bete avec des parametres...
C'est vrai que c'était évident.
 
D'ailleurs es-ce que tu masterises les macros ? Tu veux un problème bien tordu ?

Reply

Marsh Posté le 07-03-2002 à 17:07:41    

leander a écrit a écrit :

D'ailleurs es-ce que tu masterises les macros ? Tu veux un problème bien tordu ?


pas des masses, mais je veux bien un problème tordu :D (avec suffisamment de contexte)

Reply

Marsh Posté le 07-03-2002 à 17:10:01    

[citation][nom]youdontcare a écrit[/nom
ta méthode implique de changer toutes les classes dès qu'on en rajoute une. ça aussi c'est mal ;)  
[/citation]
ET entre deux maux il faut choisir le moindre...
Donc faire en fonction de la situation ;)
 
leaner >
 
La methode IsKindOf peut-tres bien etre une methode de la classe mere et comparer la chaine argument a une chaine de la classe...
chaine initialisee dans le constructeur par exemple...
 
Sur les macros des operateur comme diese ou diese-diese peuvent t'aider a la construire, mais personnellement je n'aime pas les macros, c'est casse pieds dans le deboggage...

Reply

Marsh Posté le 07-03-2002 à 17:12:17    

bon c'est un probleme que je me suis posé ce matin.
En fait, j'ai redefini le ASSERT afin qu'il soit un peu mieux que celui de Visual.
 
Et donc j'ai fais un ASSERT qui prends un nombre de parametre variable comme le printf.
Mais le problème c'est que j'arrive pas à mettre mon "__asm {int 3}" dans une macro pour que mon code s'arrete dans le cpp ou j'ai mis le assert. Tout simplement parce que le int 3 se trouve dans un fct inline et pas dans une macro. Hors comme les macros ont un nombre de parametre variables, c'est chaud...
 
Donc en fait, l'idée c'est de faire une macro ASSERT qui appele la fonction assert qui affiche le message et qui suivant le retour fait appel ou non au int 3.
 
donc un truc dans le genre (sans le int 3):
 
#define ASSERT   fct_assert
 
bool fct_assert( const char* format ...)
{
...
}
 
Et donc faut que je modifie la macro "#define ASSERT   fct_assert" pour qu'il y ai un int 3.
 
J'avais pensé à un truc dans le genre
 
#define ASSERT   __asm{int 3}  &&  fct_assert
 
Mais le problème c'est que l'opérateur || commence par évaluer de la gauche vers la droite. S'il évaluait dans l'autre sens ça me permettrait de faire marcher ma bidouille ! Parce que bien sur je n'ai pas le droit de mettre du code après le fct_assert puisque le preprocesseur va me mettre les parenthèse avec les arguments.
Donc peut-être qu'il faudrait que le retour de ma fct_assert soit une classe sur laquelle j'ai redefini un opérateur qui sera évaluer de la droite vers la gauche... Mais je ne sais pas si c'est possible...
 
C'est un peu tordu, mais s'il y en a qui aime ça ;)

Reply

Marsh Posté le 07-03-2002 à 17:15:27    

BENB a écrit a écrit :

La methode IsKindOf peut-tres bien etre une methode de la classe mere et comparer la chaine argument a une chaine de la classe...
chaine initialisee dans le constructeur par exemple...


non, car le but de isKindOf() est de renvoyer true si la classe est d'un certain type :D
 
eg
 
class A;
class B : A;
class C : B;
 
A* a = new C();
a->isKindOf("A" ); // renvoie true
a->isKindOf("B" ); // renvoie true
a->isKindOf("C" ); // renvoie true

Reply

Marsh Posté le 07-03-2002 à 17:22:08    

ca fait quoi __asm(int 3) ?
( J'ai pas d'accolades donc je mets des () )...

Reply

Marsh Posté le 07-03-2002 à 17:27:18    

BENB > breakpoint
 
leander > pourquoi pas dans la fonction ?
 
bool fct_assert( const char* format ...)  
{  
  int returnValue;
 
  if (returnValue)
  {
    _asm ...
  }
}  
 
tu n'as qu'à remonter dans la callstack pour voir où ça a breaké ...

Reply

Marsh Posté le 07-03-2002 à 17:32:34    

leander a écrit a écrit :

bon voila mon problème. J'ai le code suivant :
 
class A
{
   public: virtual ~A() {}  
};
class B : public A
{
   public: virtual ~B() {}
};
class C : public B
{
   public: virtual ~C() {}
};
 
void main()
{
   A*     pA=new C;
   B*     pB;
   C*     pC;
 
   pB = dynamic_cast<B*>(pA);
   pC = dynamic_cast<C*>(pA);
}
 
Donc pour que ce code marche il faut compiler avec les RTTI. Hors en réfléchissant un peu, je me suis dit qu'il n'y avait pas besoin du RTTI pour connaitre le type d'une classe.
 
En effet, la variable pA contient un pointeur vers la table virtuelle des fonctions. Donc normalement :hap:  à l'execution, sans rajouter d'info tel que les RTTI, le programme devrait être capable de me dire si mon objet pA est "castable" en C*.
En effet il suffit qu'il regarde si le pointeur de la table de fonction virtuelle de pA est égale à la table de fct virtuelle de C (qui est toujours la même quelque soit l'instance créer normalement).  
Et pour le cast en B*, c'est pareil, il regarde la table de fct virtuelle et le programme devrait pouvoir voir que mon pA est un C* et que donc, il peut donc le caster en B*, puisque B hérite de C.
 
Donc, es-ce qu'il y a une fonction C++ qui permet de faire ce que je dis. Sachant que toutes mes classes ont des opérateurs virtuels et qu'elles ne font pas d'héritage multiple.  
 
 




 
Le C++ n'a jamais été fait pour se poser ce genre de question  :sarcastic:  
 
Abstraction Abstraction Abstraction Abstraction

 

[jfdsdjhfuetppo]--Message édité par Tetragrammaton IHVH--[/jfdsdjhfuetppo]


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 07-03-2002 à 17:32:41    

youdontcare a écrit a écrit :

non, car le but de isKindOf() est de renvoyer true si la classe est d'un certain type :D
 
eg
 
class A;
class B : A;
class C : B;
 
A* a = new C();
a->isKindOf("A" ); // renvoie true
a->isKindOf("B" ); // renvoie true
a->isKindOf("C" ); // renvoie true  




maClasseMere::IsKindOf(std::string& testClasse)
( // c'est une accolade ouvrante :D
   size_type result = Kind.find(testClasse+";" );
   return (result != std::string::npos);
) // acolade fermante
 
dans le constructeur il suffit d'ajouter
Kind.append("MaClasseFille;" );

Reply

Marsh Posté le 07-03-2002 à 17:34:28    

parce que si je met le int 3 dans le code de ma fonction, le deboggueur va aller dans le .h de la fonction puisqu'il ne remplace pas le code comme une macro (même si je mets un __forceinline).
 
Donc c'est pour cela, que j'essaye de faire macro + fonction

Reply

Marsh Posté le 07-03-2002 à 17:35:47    

BENB a écrit a écrit :

maClasseMere::IsKindOf(std::string& testClasse)
( // c'est une accolade ouvrante :D
   size_type result = Kind.find(testClasse+";" );
   return (result != std::string::npos);
) // acolade fermante
 
dans le constructeur il suffit d'ajouter
Kind.append("MaClasseFille;" );


effectivement ! :jap:

Reply

Marsh Posté le 07-03-2002 à 17:38:02    

A la limite si tu veux faire un truc propre qui n'est pas basé sur des adresses mémoires (et donc avec des hypothèses cachées), tu peux faire ça :
 
class A
{
static enum TYPE_CLASSE {classA,classB,classC};
virtual TYPE_CLASSE retourneType() { return classA; }
  public: virtual ~A() {}  
};
 
Tu override retourneType pour chaque sous classe et c'est nettement plus simple. Et surtout, ton code ne devient pas illisible pour celui qui viendra derrière.


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 07-03-2002 à 17:38:51    

http://gcc.gnu.org/onlinedocs/gcc-3.0/cpp_3.html#SEC19
 
3.6 Variadic Macros
 
A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example:  
 
  #define eprintf(...) fprintf (stderr, __VA_ARGS__)
 
:??: ça te conviendrais pas ça ?

 

[jfdsdjhfuetppo]--Message édité par youdontcare--[/jfdsdjhfuetppo]

Reply

Marsh Posté le 07-03-2002 à 17:53:42    

- youdontcare :
pour les macros, je suis en train de tester sous visual... je vous tiens au courant, mais j'avais pas trouver ça dans la MSDN. J'avais surement pas assez chercher
 
- Tetragrammaton IHVH : c'est déjà comme ça que je fonctionnais. Pour enregistrer mes classes auprès d'une fabrique j'utilisais un système d'ID avec un enum. C'est donc comme ça que je pensais implémenter mon IsKindOf. Mais que ce soit un char* ou un ID, l'idée reste en effet la même.
En tout cas, comme toi, je préfère les IDs qui sont moins gourmand et plus rapide.

Reply

Marsh Posté le 07-03-2002 à 17:58:37    

bon, j'ai l'impression que le compilateur de Visual C++ 6.0 ne supporte pas trop les macros à multiple arguments.  En tout cas, les exemples de la page web ne marche pas !

Reply

Marsh Posté le 07-03-2002 à 18:04:10    

leander a écrit a écrit :

 
 
- Tetragrammaton IHVH : c'est déjà comme ça que je fonctionnais. Pour enregistrer mes classes auprès d'une fabrique j'utilisais un système d'ID avec un enum. C'est donc comme ça que je pensais implémenter mon IsKindOf. Mais que ce soit un char* ou un ID, l'idée reste en effet la même.
En tout cas, comme toi, je préfère les IDs qui sont moins gourmand et plus rapide.  




 
 :jap: Ouaip, "static enum" roulaizzzz comme on dit :D
 
Ca a l'avantage d'être facilement maintenable quand on ajoute une classe. Le seul stress pour les "RTTI-à-la-main" c'est de ne pas oublier d'overrider.  
J'aime pas le principe du char* car on ne differencie pas d'un autre char* qui pourrait être une chaine par exemple.


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 07-03-2002 à 18:08:55    

bon, sinon je relance mon concours de macro avec un operateur capable d'evaluer de la droite vers la gauche...
 
Parce que Visual ne gère pas les multi parametres. Pour sans convaincre il suffit de regarder leur methode de trace dans leur .h de debug.

Reply

Marsh Posté le 07-03-2002 à 18:09:33    

pour la macro si on suppose que T est un operateur qui s'evalue de droite a gauche on peut faire avec une variable :
 
(result && __asm(int 3) ) T result=assert_fct
 Ce qui supose que = est prioritaire sur T, or
1 - le seul operateur surlequel = soit prioritaire est la virgule qui s'evalue de gauche a droite...
 
2 - les seuls operateurs qui s'evaluent de droite a gauche sont  
les operatuers unaires !
les operateurs d'affectations =, +=, *=, etc...
 
Certes ceci pourrait etre une bonne nouvelle :
 = result = assert_fct s'evaluant dans le bon sens, mais ces operateurs prenent a gauche une g-value ce que le resultat d'un && n'est pas...
 
Or un operateur s'evaluant de droite a gauche est le seul moyen (a mon avis) de realiser ce que tu souhaites, hormis les macros a nombre d'argument variables bien sur...

Reply

Marsh Posté le 07-03-2002 à 18:20:06    

en effet, Benb c'est exactement ça mon problème !
 
Et il n'y a pas d'opérateur que je pourrais redéfinir sur une classe de cette façon :
(MaClass.m_bResult && __asm(int 3) ) T assert_fct  
 
ou ma fonction assert_fct renverrai une instance de MaClass...
 
class MaClass
{
public :
    void operateur T ( bool result );
 
 
  bool    m_bResult;
};
 
D'après ce que tu dis, c'est pas possible, mais bon, je pose quand même la question.

Reply

Marsh Posté le 07-03-2002 à 18:35:06    

En C++ tu ne peut pas definir d'operateurs nouveaux, uniquement redefinir les actuels...
 
en C(ANSI 89) tu as un garentie d'ordre d'execution (tous de gche a dte sauf unaires et affectation), mais en C++ (ISO 98) tu n'as plus cette garentie (sauf pour &&, le ou etc), l'ordre d'execution depends de l'implementation...
 
Certes tu pourrais chercher cet ordre, en suppoosant qu'il soit different de celui du C et fixe... mais je doute qu'un editeur de compilo se soit amuse a faire cela, et les rares qui ne doivent pas suivre les regles du C doivent le faire en fonction de parametre d'optimisation. De plus je ne te conseille pas de t'amuser a utiliser une telle "fonctionnalite" qui pourrait changer d'une version de compilo a l'autre (sans parler d'un pb de portage)...
 
Quand a la creation d'operateurs, je ne sais pas comment cela est gere par les langages qui authorisent cela (Ada par ex) mais il y le Pb de la priorite et de l'ordre d'execution !
 
je resume  
a = f(x) + g(x)
en C ansi 89 f est evaluee avant g, et en C++(ISO98) cela depend du compilo...
 
donc ce qui serait le plus proche serait
 
(result && __asm(int 3)) = result = fct_assert
 
fct_assert serait evalue, puis result recevrait sa valeur
puis (result && __asm(int 3)) serait evalue et recevrait la valeur de result... c'est tordu, tres tordu et ne marche pas car le terme de gauche du second = n'est pas une g-valeur...

Reply

Marsh Posté le 07-03-2002 à 18:41:14    

Pardon
((result && __asm(int 3),result) = result = fct_assert
 
j'utilise l'operateur virgule donc  
 
((result && __asm(int 3),result) est une g-value (je crois)
 mais je n'ais pas compile...

Reply

Marsh Posté le 07-03-2002 à 18:54:06    

tu n'es pas loin !!
 
 
chez moi  
((result && true,result) = result = fct_assert
 
compil !!! Par contre, le fait de mettre __asm {int 3} à la place de true, ça plante à la compilation.

Reply

Marsh Posté le 07-03-2002 à 20:23:33    

leander a écrit a écrit :

tu n'es pas loin !!
 
 
chez moi  
((result && true,result) = result = fct_assert
 
compil !!! Par contre, le fait de mettre __asm {int 3} à la place de true, ça plante à la compilation.  




 
Ca plante ?
quelle erreur ?

Reply

Marsh Posté le 07-03-2002 à 20:32:06    

( b && __asm {int 3}, b ) = fct_assert();
 
 
main.cpp(60) : error C2059: syntax error : '__asm'
main.cpp(60) : error C2143: syntax error : missing ';)' before '{'
main.cpp(60) : error C2143: syntax error : missing ';' before '{'
main.cpp(60) : warning C4091: '' : ignored on left of 'int' when no variable is declared
main.cpp(60) : error C2143: syntax error : missing ';' before 'constant'
main.cpp(60) : error C2143: syntax error : missing ';' before '}'
main.cpp(60) : error C2143: syntax error : missing ';' before ','
main.cpp(60) : error C2059: syntax error : ';)'

Reply

Marsh Posté le 07-03-2002 à 23:10:36    

La macro doit ressembler a ca
 
#define ASSERT bool b; \
  ((result && __asm{int 3}),result) = result = fct_assert  
 
je ne vois pas vraiment le Pb sinon le fait que __asm ne renvoie rien...
 
#define ASSERT bool b; \
  ((result && (__asm{int 3},true)),result) = result = fct_assert  
 
ou je remplace le __asm{int 3} par un operateur virgule
(__asm{int 3},true)... qui lui renvoie quelque chose....
 
bon deja au depart c'etait pas genial, maintenant c'est completement illisible.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed