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.18), ç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/
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Horst Kraemer
On Sun, 25 Apr 2004 10:44:34 +0200, Vincent Richard wrote:
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.
Si j'enlève les 'class' (l.15 et l.18), ç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();
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
On Sun, 25 Apr 2004 10:44:34 +0200, Vincent Richard
<chere-loque.MARRE-DE-LA-PUB@wanadoo.fr.invalid> wrote:
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.
Si j'enlève les 'class' (l.15 et l.18), ç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();
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.
On Sun, 25 Apr 2004 10:44:34 +0200, Vincent Richard wrote:
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.
Si j'enlève les 'class' (l.15 et l.18), ç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();
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
Vincent Richard
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.18), ç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).
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/
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.18), ç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).
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/
class test* test() { return m_test; } // ligne 19 };
[...] Si j'enlève les 'class' (l.15 et l.18), ç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).
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/
Vincent Richard
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/
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/
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/
Gabriel Dos Reis
Vincent Richard writes:
| 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
Vincent Richard <chere-loque.MARRE-DE-LA-PUB@wanadoo.fr.invalid> writes:
| 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.
| 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
kanze
Vincent Richard wrote in message news:<408bbd90$0$19503$...
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.18), ç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++.
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 :
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: 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
Vincent Richard <chere-loque.MARRE-DE-LA-PUB@wanadoo.fr.invalid> wrote
in message news:<408bbd90$0$19503$636a15ce@news.free.fr>...
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.18), ç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++.
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 :
Vincent Richard wrote in message news:<408bbd90$0$19503$...
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.18), ç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++.
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 :