 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Vincent Richard Guest
|
Posted: Sun Apr 25, 2004 8:44 am Post subject: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
Bonjour,
Je viens de passer à la version 3.4 de g++ et le code suivant ne
compile plus :
class A { };
typedef A test; // ligne 8
class B
{
private:
class test* m_test; // ligne 15
public:
class test* test() { return m_test; } // ligne 19
};
L'erreur :
td.cpp:15: error: using typedef-name `test' after `class'
td.cpp:19: error: using typedef-name `test' after `class'
Si j'enlève les 'class' (l.15 et l.1 , ça passe avec la version 3.4 mais ça
ne compile plus avec la version 3.3 :
td.cpp:19: error: declaration of `test* B::test()'
td.cpp:8: error: changes meaning of `test' from `typedef class A test'
Comment résoudre le problème en gardant le même nom pour la fonction, sans
renommer la classe et pour que ça fonctionne avec les deux version des
compilateurs ?
Merci d'avance pour vos réponses.
Vincent
--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/
|
|
| Back to top |
|
 |
Horst Kraemer Guest
|
Posted: Sun Apr 25, 2004 10:35 am Post subject: Re: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
On Sun, 25 Apr 2004 10:44:34 +0200, Vincent Richard
<chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> wrote:
| Quote: | Je viens de passer à la version 3.4 de g++ et le code suivant ne
compile plus :
class A { };
typedef A test; // ligne 8
class B
{
private:
class test* m_test; // ligne 15
public:
class test* test() { return m_test; } // ligne 19
};
L'erreur :
td.cpp:15: error: using typedef-name `test' after `class'
td.cpp:19: error: using typedef-name `test' after `class'
|
'class test' était toujours illégal selon la norme (7.1.3, par.4)
après
class A;
typedef A test;
bien qu'il y ait des compilateurs qui l'acceptent.
| Quote: | Si j'enlève les 'class' (l.15 et l.1 , ça passe avec la version 3.4 mais ça
ne compile plus avec la version 3.3 :
td.cpp:19: error: declaration of `test* B::test()'
td.cpp:8: error: changes meaning of `test' from `typedef class A test'
|
C'est normal. 'test' est un nom de classe qui est au même niveau qu'un
nom de fonction. C'est aussi illégal que
class A;
void A();
| Quote: | Comment résoudre le problème en gardant le même nom pour la fonction, sans
renommer la classe et pour que ça fonctionne avec les deux version des
compilateurs ?
|
Impossihle. Un typedef 'test' et une fonction 'test' ne peuvent pas
coexister et 'class test' est illégal si test est un typedef.
Laisser tomber le typedef. Quel est l'intérêt ? Ou changer le nom du
typedef.
--
Horst
|
|
| Back to top |
|
 |
Vincent Richard Guest
|
Posted: Sun Apr 25, 2004 1:33 pm Post subject: Re: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
Le Sunday 25 April 2004 12:35 pm, Horst Kraemer a écrit :
| Quote: | class A { };
typedef A test; // ligne 8
class B
{
private:
class test* m_test; // ligne 15
public:
class test* test() { return m_test; } // ligne 19
};
[...]
Si j'enlève les 'class' (l.15 et l.1 , ça passe avec la version 3.4 mais
ça ne compile plus avec la version 3.3 :
td.cpp:19: error: declaration of `test* B::test()'
td.cpp:8: error: changes meaning of `test' from `typedef class A test'
C'est normal. 'test' est un nom de classe qui est au même niveau qu'un
nom de fonction.
|
Pourtant l'un est un type (défini dans l'espace de nom global, puisque
"class test" est censé y faire référence et non déclarer un nouveau type)
et l'autre une fonction (définie dans la classe B). Et la version 3.4 de
g++ fait bien la différence puisque je peux écrire :
class test;
struct B { test* test(); }
qui est correct, me semble-t-il.
Mais je pense que c'est une limitation du parseur de g++ 3.3 qui ne
parvient pas à distinguer les deux cas (contexte).
| Quote: | Comment résoudre le problème en gardant le même nom pour la fonction,
sans renommer la classe et pour que ça fonctionne avec les deux version
des compilateurs ?
Impossihle. Un typedef 'test' et une fonction 'test' ne peuvent pas
coexister et 'class test' est illégal si test est un typedef.
Laisser tomber le typedef. Quel est l'intérêt ? Ou changer le nom du
typedef.
|
Ici, j'utilise le typedef pour faire un alias d'un nom de classe (pour la
clarté du code). Pour éviter des #define...
J'ai trouvé une solution provisoire, mais pas très élégante :
class A { };
class test : public A { };
class B
{
class test* test() { ... }
}
Vincent
--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/
|
|
| Back to top |
|
 |
Vincent Richard Guest
|
Posted: Sun Apr 25, 2004 1:45 pm Post subject: Re: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
Le Sunday 25 April 2004 03:33 pm, Vincent Richard a écrit :
| Quote: | J'ai trouvé une solution provisoire, mais pas très élégante :
class A { };
class test : public A { };
class B
{
class test* test() { ... }
}
|
Je viens de me rendre compte que je pouvais écrire tout simplement :
namespace X
{
class A { };
typedef A test;
class B
{
X::test m_test;
X::test* test() { return m_test; }
}
};
Désolé pour le dérangement...
Vincent
--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sun Apr 25, 2004 1:58 pm Post subject: Re: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
Vincent Richard <chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> writes:
| Quote: | class test;
struct B { test* test(); }
qui est correct, me semble-t-il.
|
Non. C'est invalide -- mais la norme ne demande pas de diagnostique.
Les récentes versions de GCC avant 3.4.0 arrivaient à le diagnostique
mais quelqu'un introduit une regression dans le compilatur à ce
niveau. Je me rappelle que le problème a été rapporté il y a peu.
-- Gaby
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Apr 26, 2004 7:16 am Post subject: Re: Passage g++ 3.3 --> 3.4 : erreur typedef |
|
|
Vincent Richard <chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> wrote
in message news:<408bbd90$0$19503$636a15ce (AT) news (DOT) free.fr>...
| Quote: | Le Sunday 25 April 2004 12:35 pm, Horst Kraemer a écrit :
class A { };
typedef A test; // ligne 8
class B
{
private:
class test* m_test; // ligne 15
public:
class test* test() { return m_test; } // ligne 19
};
[...]
Si j'enlève les 'class' (l.15 et l.1 , ça passe avec la version
3.4 mais ça ne compile plus avec la version 3.3 :
td.cpp:19: error: declaration of `test* B::test()'
td.cpp:8: error: changes meaning of `test' from `typedef class A test'
C'est normal. 'test' est un nom de classe qui est au même niveau
qu'un nom de fonction.
Pourtant l'un est un type (défini dans l'espace de nom global, puisque
"class test" est censé y faire référence et non déclarer un nouveau
type) et l'autre une fonction (définie dans la classe B).
|
Ça fait rien.
En général, en C++, à l'encontre de C, tous les noms sauf des étiquettes
(cibles des goto) se trouvent dans le même espace -- tu ne peux pas
avoir un type et une fonction avec le même nom dans le même espace
référenciel. (Et est-ce que quelqu'un a une idée comment je pourrais
distinguer entre ces deux significations d'espace référentiel ?) Il y a
une exception, un cas spécial qui existe pour la compatibilité C, qui
permet à un nom de classe (pas un nom de type quelconque) à cohabiter
avec le même nom de fonction ou de variable, mais c'est un cas
particulier (on dirait même un hack) pour la compatibilité C, AMHA à
éviter dans le code proprement C++.
| Quote: | Et la
version 3.4 de g++ fait bien la différence puisque je peux écrire :
class test;
struct B { test* test(); }
qui est correct, me semble-t-il.
|
Je ne crois pas. Correct serait :
class test ;
struct B { class test* test() ; } ;
Mais je ne suis pas 100% certain. Comme j'ai dit, c'est un hack pour de
raisons de compatibilité C, et je ne m'en sers (et ne m'en intéresse)
que dans le cas où ce que j'écris est réelement compatible dans les deux
langages. Quelque chose du genre :
#ifdef __cplusplus
extern "C" {
#endif
struct X { /* ... */ } ;
X* createX() ;
void doSomethingWithX( struct X* ) ;
/* ... */
#ifdef __cplusplus
}
#endif
| Quote: | Mais je pense que c'est une limitation du parseur de g++ 3.3 qui ne
parvient pas à distinguer les deux cas (contexte).
|
Sauf pour le hack de compatibilité, on ne doit pas avoir le même symbole
dans la même portée avec deux significations différentes.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|