OVH Cloud OVH Cloud

membres d'une base dépendante ?

48 réponses
Avatar
Dimitri Papadopoulos-Orfanos
Bonjour,

Le code suivant n'est plus compilé par des compilateurs récents tels que
gcc 3.4 :

template <typename T> struct A {
int x;
};
template <typename T> struct B : public A<T> {
void foo() { x = 1; }
};

L'erreur est:
foo.cc: In member function `void B<T>::foo()':
foo.cc:5: error: `x' undeclared (first use this function)
foo.cc:5: error: (Each undeclared identifier is reported only once for each
function it appears in.)

Les notes de gcc 3.4 parlent bien de ce changement :
In a template definition, unqualified names will
no longer find members of a dependent base.

Toutefois je n'arrive pas à trouver le paragraphe du chapitre 14 de la
norme C++ qui le justifient. C'est probablement caché dans 14.6 mais
j'ai du mal à suivre les paragraphes en question... Quelqu'un peut-il me
montrer le paragraphe qui s'applique à ce cas ?

Qu'est-ce qu'une "base dépendante" ? Pourquoi faire un cas spécial pour
les templates ?

Merci d'avance,
Dimitri

10 réponses

1 2 3 4 5
Avatar
google
wrote
Gabriel Dos Reis wrote in message
news:...
Dimitri Papadopoulos-Orfanos
writes:

| réécrire des centaines de classes. Chose que je ne peux pas faire.
| Je pense que genre de changements met en cause la pertinence du C++
| pour l'écriture de gros projets destinés à vivre plusieurs années.

Ces règles n'ont pas été inventées hier.
[...]


Elles datent du temps même de la conception des templates.


Tu veux dire comme au temps de l'ARM ? Ou qu'elles étaient implémentées
dans CFront 3.0 ? N'exagérons rien.


Elles n'etaient certainement pas implementees dans Cfront 3.0,
mais l'ARM en fait ne parle pas du probleme du tout. Le fait que
l'ARM a une grammaire pour les templates me fait soupconner
qu'en fait l'intention etait que les templates soit "parsees" dans
leur formes generiques, et donc des regles differentes de celles
de Cfront etaient envisagees.

(Trivia: Cfront 3.0 etait une version essentiellement inutilisable
du au grand nombre de bogues. La version 3.0.1 corrigait les
problemes les plus grossiers, et fut le premier compilo a vraiment
permettre l'exploration des templates. Neanmoins, de beaucoup
de points de vues, l'implementation Cfront des templates etait
un "hack" que la plupart des implementation ulterieures etaient
forcees d'imiter.)

(Comme d'habitudes, mes excuses pour les fautes d'ortographe.)

David


Avatar
google
Gabriel Dos Reis wrote:
[ ... a propos des regles templates a deux phases ... ]
| > Elles datent du temps même de la conception des templates.
|
| Tu veux dire comme au temps de l'ARM ? Ou qu'elles étaient implémentées
| dans CFront 3.0 ? N'exagérons rien.

Ce que tu ne sais pas, c'est que les templates dans CFront ne sont pas
implémentés par son concepteur, ni par le « maintainer officiel. »
Mais par un utilisateur C++ qui avait lu certaines descriptions.
[...]


Gabriel a raison, mais peut-etre que James le sait puisque c'est
aussi decrit dans D&E (p. 339). Plus specifiquement, Object Design
(ODI) avait implemente en 1989 les "class templates" dans leurs
copie de Cfront 2.x (ils avaient une licence pour la source). Ils ont
ensuite donne cette implementation a USL qui y ajoute les "function
templates" sous la direction de Stan Lippman (maintenant a Microsoft).
Ca c'etait Cfront 3.0 (Septembre 1991), mais en pratique cette version
ne marchait pas. John Spicer (maintenant mon collegue a EDG) a
ensuite pris la place de Stan Lippman pour produire Cfront 3.0.1 qui
etait au moins utilisable (mais pas vraiment super-solide non plus).

(Comme d'habitude, mes excuses pour les fautes de francais.)

David

Avatar
kanze
Gabriel Dos Reis wrote in message
news:...
writes:
| Gabriel Dos Reis wrote in message
| news:...
| > Dimitri Papadopoulos-Orfanos
| > writes:

| > | réécrire des centaines de classes. Chose que je ne peux pas
| > | faire. Je pense que genre de changements met en cause la
| > | pertinence du C++ pour l'écriture de gros projets destinés à
| > | vivre plusieurs années.

| > Ces règles n'ont pas été inventées hier.

| Qu'importe quand elles ont été inventées.

Cela importe parce que l'histoire de cette règle fait partie de la
confusion et de ses conséquences.


L'histoire est certes importante. Mais pas l'histoire d'une règle prise
en isolation. L'histoire comporte bien ce qu'a pû penser les auteurs de
la norme, à une certaine époque. Mais une partie plus importante, c'est
bien ce que faisait les premières implémentations.

| Elles ne sont pas particulièrement intuitives.

« intuitives » est une question d'opinion, et non une vérité. Je ne me
fierais pas à ton intuition -- je me méfies déjà de la mienne.


Disons que ce n'est pas que la mienne. Les questions sur le sujet
pourraient faire partie de la FAQ de clc++m. Et je vois les problèmes
qu'on les collègues ici, depuis qu'on a ajouté g++ 3.4 à la liste des
compilateurs « obligatoires ».

| Surtout, elles représentent un changement par rapport à ce que les
| compilateurs faisaient jusqu'il y a peu.

On a eu ce débat plusieurs fois. À chaque fois, tu répètes les mêmes
choses et à chaque fois tu dois te faire corriger. Par moi, ou par
David Vendevoorde. Je ne désespère pas qu'un jour cela va rentrer.


D'abord, je ne répètes pas la même chose. Je ne savais réelement pas que
l'idée de la récherche à deux phases étaient aussi ancienne avant que tu
me l'as indiqué. Depuis, je ne le dis pas.

Mais d'où venait l'idée n'était jamais un aspect important de ma
critique. Le problème prémordial, au moins pour ceux d'entre nous dont
le travail est d'écrire des programmes qui marchent, c'est que les
compilateurs ne l'ont pas implémenté. (Évidemment, je ne peux pas parler
de tous les compilateurs. Mais CFront ne l'a jamais implémenté, g++ pas
avant 3.quelque chose, Sun CC pas encore, et VC++ au moins pas encore
dans 6.0.) Alors, il s'avère que même des gens comme moi, qui évitent
évité de se précipiter à des nouveautés, se sont fait avoir. Et se
rétrouvent avec une quantité de code importante qui ne se compile pas.
Et des « habitudes » et des « intuitiions » qui ne le prenent pas en
compte.

Les compilateurs ont choisi d'ignorer la règle, cela ne veut pas dit
qu'elle date d'hier.


Personne ne dit le contraire. Le problème, c'est que pour compiler mon
code, il faut que je me conforme aux compilateurs, non à la norme.

Je t'ai déjà donné des références publiques remontant au moins à 1992,
qui montrent que la notion de recherche en deux phases étaient
considérées bien avant qu'on ait eu les aspects les plus avancés des
templates.


Et depuis, je n'ai pas dit de contraire. C'est bien. L'idée date de
1992. Voire même avant, parce que j'imagine que les gens en ont discuté
avant d'écrire des papiers.

[...]
| > Elles datent du temps même de la conception des templates.

| Tu veux dire comme au temps de l'ARM ? Ou qu'elles étaient
| implémentées dans CFront 3.0 ? N'exagérons rien.

Ce que tu ne sais pas, c'est que les templates dans CFront ne sont pas
implémentés par son concepteur, ni par le « maintainer officiel. »


Je ne le savais pas, en effet. Mais ça ne change pas le fait que le
premier compilateur à supporter les templates, et pendant un certain
temps le seul, c'était CFront. Et que c'est le compilateur qui a servi à
beaucoup d'entre nous à les apprendre. Lire la norme, c'est beau, si tu
veux, mais moi, je ne comprends quelque chose que si je l'ai réelement
pratiqué. Or, jusqu'il y a peut-être un an (la sortie de g++ 3.1, grosso
modo), je n'ai pas eu accès à un compilateur qui supportait la récherche
à deux phases.

Mais par un utilisateur C++ qui avait lu certaines descriptions.
L'implémentation qui était livrée avec CFront ne contient pas tout ce
que le concepteur des templates envisageait.


Peut-être. À l'époque, je n'avais que deux sources d'information réele,
CFront et l'ARM. Et elles ne se contradisaient pas. Pourquoi est-ce que
je devais imaginer que le concepteur des templates (qui était quand même
co-auteur de l'ARM) envisageait quelque chose d'autre.

| La situation est complexe. L'idée d'utiliser une recherche à deux
| temps est apparue assez vite (2-3 ans ?) après les premières
| implémentations des templates, et bien avant la plupart des
| implémentations.

Tu doutes que je travaille pour celui qui a conçu les templates, que
je travaille tous les jours sur les templates avec celui qui les a
conçus et qu'on discute quotidiennement des points techniques,
non-techniques et de son histoire ; et donc que j'ai accès à
l'information de première main que les allégations très approximatives
que racontes ?


Quelles allégations ? Il y a un document écrit, l'ARM, qui n'en parle
pas. Il y a une implémentation, qui n'en parle pas. Est-ce que tu nies
ça ? C'est tout ce que je dis.

Le premier papier écrit que tu m'as montré sur le sujet date de 1992.
L'ARM, de 1989, et CFront 3.0 d'environ la même date.

| Je crois que l'intention d'imposer une recherche à deux temps est
| apparue assez tôt dans le groupe de travail qui s'occupait des
| templates dans le comité de normalisation.

Tu racontes cela comme si tu y étais,


Tu as une drôle de façon à interpréter le français. J'ai clairement dit
que je parlais de mes impressions. Basées, évidemment, sur ce que j'ai
lu.

alors même que tu ne savais pas que cela existait jusqu'à ce que je te
montre le papier en question et que tu me répondes quelque chose du
genre « eh bin, peut-être qu'ils en parlaient, mais moi je n'étais pas
dans ce groupe, et puis de toute façon, même ceux qui savaient n'en
parlaient pas, et puis j'ai raison. » <G>.


Tu aurais l'air un peu moins idiote si tu parlais de ce que j'ai écrit,
à la place d'imaginer je ne sais quoi.

J'ai déjà écrit que moi, je n'avais par remarqué l'existance de la
récherche en deux phases jusqu'à un époque assez tardif. Je croyais,
alors, que c'était réelement à un époque tardif qu'elle a apparue. Tu as
cité des papiers du groupe du travail qui m'a convaincu du contraire.
C'est bien toi qui m'as fait penser que c'est dans le groupe de travail
que l'idée s'est fait. Mais si tu as des papiers encore plus anciens à
me citer, je suis près à les croire.

| Ce qui veut dire que les implémenteurs des compilateurs en étaient
| probablement au courants, au moins pour la plupart. Ils ont
| effectivement choisi de l'ignorer, de façon à ce que leurs
| utilisateurs aient davantage de problèmes maintenant.

Et David Vandevoorde t'a raconté son expérience personnelle de
l'époque où il travaillait sur le compilateur d'HP. Ils avaient
implémenté la règle en question vers 1997 ; après des tests sur des
programmes, ils avaient décidé de désactiver.


Ce que je n'ai contradit nulle part. Au cas où tu n'es pas au courant,
il existait des gens qui faisaient du C++ bien avant 1997.

Et comme David le rappelle à chaque fois, cette règle est discutée
dans D&E.


D&E explique qu'il y a une implémentation vers 1997 ? (Il me semble que
le livre est apparu avant ça. Mais ce n'est que mes souvenirs.)

| Pour monsieur tout le monde, évidemment, les templates, c'était ce
| que faisait CFront, étant donné que c'était le seul compilateur qui
| les implémentait. Pendant longtemps, d'ailleurs, ce que faisait
| CFront faisait figure de norme pour les utilisateurs et les autres
| implémenteurs. Jusqu'au point d'en dupliquer les bugs. Même
| aujourd'hui, certains compilateurs conforme (exprès) plus à ce que
| faisait CFront qu'à la norme.

| > Certaines personnes (avec le complice de certains compilateurs)
| > essayeront de te faire croire que c'est pas vrai.

| Tu peux montrer qui, et où ?

Ben lis tes deux messages, je n'ai pas besoin d'aller chercher plus
loin. Ou fais un google pour tes messages dans ce groupe où toi et moi
en avons discuté, ou dans comp.lang.c++.moderated ou comp.std.c++ où
David Vandevoorde était intervenu.


J'ai bien du dire il y a longtemps que je croyais que c'était récent.
Parce que je ne savais pas des discussions dans le comité, et je me
jugais d'après ce que faisaient les compilateurs.

Mais ce que j'ai surtout dit, et ce que je dis toujours, c'est que son
implémentation est récente. Et qu'elle a pris bien de programmeurs à
dépourvu.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
(Daveed Vandevoorde) wrote in message
news:...
Gabriel Dos Reis wrote:
[ ... a propos des regles templates a deux phases ... ]
| > Elles datent du temps même de la conception des templates.

| Tu veux dire comme au temps de l'ARM ? Ou qu'elles étaient
| implémentées dans CFront 3.0 ? N'exagérons rien.

Ce que tu ne sais pas, c'est que les templates dans CFront ne sont pas
implémentés par son concepteur, ni par le « maintainer officiel. »
Mais par un utilisateur C++ qui avait lu certaines descriptions.


[...]

Gabriel a raison, mais peut-etre que James le sait puisque c'est aussi
decrit dans D&E (p. 339). Plus specifiquement, Object Design (ODI)
avait implemente en 1989 les "class templates" dans leurs copie de
Cfront 2.x (ils avaient une licence pour la source). Ils ont ensuite
donne cette implementation a USL qui y ajoute les "function templates"
sous la direction de Stan Lippman (maintenant a Microsoft). Ca c'etait
Cfront 3.0 (Septembre 1991), mais en pratique cette version ne
marchait pas. John Spicer (maintenant mon collegue a EDG) a ensuite
pris la place de Stan Lippman pour produire Cfront 3.0.1 qui etait au
moins utilisable (mais pas vraiment super-solide non plus).


Non, je ne le savais pas. Aussi, je dis souvent CFront 3.0, parce que
c'est dans 3.0 qu'ils ont apparu officiellement pour la première fois.
Mais le 3.0, c'était bien un .0, et je ne me suis jamais servi d'un .0
dans le travail.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
(Daveed Vandevoorde) wrote in message
news:...
wrote
Gabriel Dos Reis wrote in message
news:...
Dimitri Papadopoulos-Orfanos
writes:

| réécrire des centaines de classes. Chose que je ne peux pas
| faire. Je pense que genre de changements met en cause la
| pertinence du C++ pour l'écriture de gros projets destinés à
| vivre plusieurs années.

Ces règles n'ont pas été inventées hier.
[...]


Elles datent du temps même de la conception des templates.


Tu veux dire comme au temps de l'ARM ? Ou qu'elles étaient
implémentées dans CFront 3.0 ? N'exagérons rien.


Elles n'etaient certainement pas implementees dans Cfront 3.0, mais
l'ARM en fait ne parle pas du probleme du tout.


L'ARM était en effet assez vague en ce qui concerne les templates.
Personellement, j'ai l'impression d'avoir lu quelque part que les
châpitres sur les templates et sur les exceptions étaient
« expérimentales ». En revanche, je n'arrive pas à trouver où.

Le fait que l'ARM a une grammaire pour les templates me fait
soupconner qu'en fait l'intention etait que les templates soit
"parsees" dans leur formes generiques, et donc des regles differentes
de celles de Cfront etaient envisagees.


Je crois que tout le monde reconnaissait que la solution CFront était un
hack. Un hack bien utile, évidemment ; ceux de nous qui avaient
implémenté des classes génériques à la base de <generic.h> en attendait
avec impatience.

(Trivia: Cfront 3.0 etait une version essentiellement inutilisable du
au grand nombre de bogues.


C'est le cas habituel des vrai .0, malheureusement. Encore que quand tu
considères ce dont on avait l'habitude à l'époque... (Jusqu'en 94
environ, je comptais deux boggues dans le compilateur pour chaque erreur
dans mon propre code. Avec des compilateurs « stabiles ».)

La version 3.0.1 corrigait les problemes les plus grossiers, et fut le
premier compilo a vraiment permettre l'exploration des templates.
Neanmoins, de beaucoup de points de vues, l'implementation Cfront des
templates etait un "hack" que la plupart des implementation
ulterieures etaient forcees d'imiter.)


Parce que c'était CFront. Le compilateur « officiel ».

C'est intéressant de savoir l'histoire de CFront maintenant. Mais il ne
faut pas oublier qu'à l'époque, c'était le compilateur qui sortait de
AT&T. La référence. Les (ré)vendeurs n'ont certainement pas tiré notre
attention sur le faut que ce n'était plus l'oeuvre de l'équipe Bell
Labs.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
kanze
Samuel Krempp wrote in message
news:<415d1303$0$6180$...
le Friday 17 September 2004 08:47, écrivit :
N'empêche que l'idée de base me semble bien -- seulement, je n'aime
pas que ce soit le compilateur (et non moi) qui choisit quels noms
sont dépendants, et quels noms ne le sont pas, d'une façon assez
subtile et non toujours très transparente.


en l'occurence, pour rendre le nom dépendant, on a le choix entre :

template <typename T> struct B : public A<T> {
typedef A<T> base_type; // dependant base
void foo() { base_type::x = 1; }
};

et
template <typename T> struct B : public A<T> {
void foo() { this->x = 1; }
};
, non ?

y-a-t'il des arguments pour préferer l'un ou l'autre ?

(j'aurais tendance à prendre la 2° façon, plus courte et qui ne dit
que ce qu'il faut : il s'agit d'un membre)


Moi aussi. Aussi parce que si x est une fonction virtuelle, elle ne
bloque pas la virtualité.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Jean-Marc Bourguet
writes:

L'ARM était en effet assez vague en ce qui concerne les templates.
Personellement, j'ai l'impression d'avoir lu quelque part que les
châpitres sur les templates et sur les exceptions étaient «
expérimentales ». En revanche, je n'arrive pas à trouver où.


Ne serait-ce pas dans la deuxieme edition de TC++PL? (Je ne l'ai pas
sous la main, mais j'ai le souvenir de l'avoir lu quelque part).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Gabriel Dos Reis
writes:

[...]

| Mais d'où venait l'idée n'était jamais un aspect important de ma
| critique. Le problème prémordial, au moins pour ceux d'entre nous dont
| le travail est d'écrire des programmes qui marchent, c'est que les
| compilateurs ne l'ont pas implémenté.

Ceux d'entre vous dont le souci premier est d'écrire des programmes
qui marchent auraient dû savoir que « this->f() » marche dans
les deux cas (recherche de noms en deux phases ou non).

[...]

| > | Je crois que l'intention d'imposer une recherche à deux temps est
| > | apparue assez tôt dans le groupe de travail qui s'occupait des
| > | templates dans le comité de normalisation.
|
| > Tu racontes cela comme si tu y étais,
|
| Tu as une drôle de façon à interpréter le français.

Tu parles de toi ?

[...]

| > Et comme David le rappelle à chaque fois, cette règle est discutée
| > dans D&E.
|
| D&E explique qu'il y a une implémentation vers 1997 ? (Il me semble que
| le livre est apparu avant ça. Mais ce n'est que mes souvenirs.)

La preuve par l'exemple de

# Tu as une drôle de façon à interpréter le français.

Merci James, tu es ton meilleur contradicteur ;-p

-- Gaby
Avatar
Dimitri Papadopoulos-Orfanos
Hi,

Ceux d'entre vous dont le souci premier est d'écrire des programmes
qui marchent auraient dû savoir que « this->f() » marche dans
les deux cas (recherche de noms en deux phases ou non).


Hum, comment peut-on le savoir ? Je sais bien que nul n'est censé
ignorer la loi, mais de là à demander aux programmeurs C++ de comprendre
la norme C++... Si c'était le cas, il n y'aurait plus beaucoup de
prorgammeurs C++.

J'aimais bien le C++ quand j'étais plus jeune et que je travaillais avec
une poignée de gens qui comprennaient les très nombreuses subtilités de
ce langage. Avec l'âge, le recul, la nécessité de travailler avec des
programmeurs moins pointus, de maintenir du vieux code, etc. eh bien je
ne conseillerais à personne de démarrer un nouveau projet en C++. Mieux
vaut utiliser Java, C#, Python ou Objective-C, avec éventuellement C/C++
pour les parties à optimiser. C'est vraiment terrible de travailler avec
un langage qui nécessite des études de "droit du langage informatique"
pour faire des programmes qui tiennent plus de deux-trois ans.

Dimitri

Avatar
google
wrote:
[...]
L'ARM était en effet assez vague en ce qui concerne les templates.
Personellement, j'ai l'impression d'avoir lu quelque part que les
châpitres sur les templates et sur les exceptions étaient
« expérimentales ». En revanche, je n'arrive pas à trouver où.


D&E mentionne que l'ARM limitait les templates (pas tellemens dans
le sense de "vague", mais plutot dans le sense de "fonctionalites")
parce qu'il y avait trop peu d'experience dans le domaine, et qu'il
etait plus facile d'ajoute que de soustraire.

Aussi, note que la premiere impression de l'ARM apparut une bonne
annee avant Cfront 3.0. (Mais pendant ce temps, ODI travaillait deja
sur le "class templates".)

Le fait que l'ARM a une grammaire pour les templates me fait
soupconner qu'en fait l'intention etait que les templates soit
"parsees" dans leur formes generiques, et donc des regles differentes
de celles de Cfront etaient envisagees.


Je crois que tout le monde reconnaissait que la solution CFront était un
hack.


Mal implemente, en plus :-(

Un hack bien utile, évidemment ; ceux de nous qui avaient
implémenté des classes génériques à la base de <generic.h> en attendait
avec impatience.

(Trivia: Cfront 3.0 etait une version essentiellement inutilisable du
au grand nombre de bogues.


C'est le cas habituel des vrai .0, malheureusement.


J'espere que non ;-) Beaucoup de .0 on en effet trop de bogues, mais
Cfront 3.0 etait literalement inutilisable.

Encore que quand tu
considères ce dont on avait l'habitude à l'époque... (Jusqu'en 94
environ, je comptais deux boggues dans le compilateur pour chaque erreur
dans mon propre code. Avec des compilateurs « stabiles ».)


Ah, la bonne epoque... ;-)

La version 3.0.1 corrigait les problemes les plus grossiers, et fut le
premier compilo a vraiment permettre l'exploration des templates.
Neanmoins, de beaucoup de points de vues, l'implementation Cfront des
templates etait un "hack" que la plupart des implementation
ulterieures etaient forcees d'imiter.)


Parce que c'était CFront. Le compilateur « officiel ».

C'est intéressant de savoir l'histoire de CFront maintenant. Mais il ne
faut pas oublier qu'à l'époque, c'était le compilateur qui sortait de
AT&T. La référence. Les (ré)vendeurs n'ont certainement pas tiré notre
attention sur le faut que ce n'était plus l'oeuvre de l'équipe Bell
Labs.


Oui, malheureusement. En fait, c'est un cas ou le standard est arrive
"trop tard". Ou, en d'autres termes, ou "standardiser la pratique
existante" n'etait pas la bonne chose a faire.

David


1 2 3 4 5