Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a
déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo;
typedef int Foo;
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger de
montrer une définition. Dans $7.1.3.3, Je note aussi que le diagnostic
indiqué de «typedef int complex;» (suite à class complex { /*
... */};) est une redéfinition (alors que typedef fait une
déclaration).
En fait, ce serait pas mal qu'un «typedef-name» soit un «class-name»,
même s'il ne nommme pas une classe. Je suppose que cela serait source
de problèmes, mais, si c'est bien le cas, j'avoue ne pas le(s) voir du
premier coup d'oeil.
Je suppose que ceci est légal : class Foo; typedef int Foo;
Et je fais :
class Foo; typedef int Foo;
void f( int& ); void f( Foo& );
//je défini les f plus tard.
Les déclarations identiques dont je parlais sont celles de f.
-- Fab
James Kanze
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Note bien qu'on ne pourrait pas permettre une utilisation de Foo entre les deux, parce que rien ne garantit que la taille et le format des pointeurs vers une classe sont identiques à ceux vers un int -- et l'intérêt de « class Foo ; », c'est bien de pouvoir déclarer un « Foo* ».
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger de montrer une définition. Dans $7.1.3.3, Je note aussi que le diagnostic indiqué de «typedef int complex;» (suite à class complex { /* ... */};) est une redéfinition (alors que typedef fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration définit bien le symbole (sinon l'objet, le type ou la fonction que le symbole désigne).
En fait, ce serait pas mal qu'un «typedef-name» soit un «class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse pas implémenter avec les techniques courantes.
Je suppose que cela serait source de problèmes, mais, si c'est bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le name-mangling:
class Foo ; void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ... typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose comme ça... { }
-- James Kanze 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
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme
a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo;
typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui
pouvait être l'intérêt de le permettre ?
Note bien qu'on ne pourrait pas permettre une utilisation de Foo
entre les deux, parce que rien ne garantit que la taille et le
format des pointeurs vers une classe sont identiques à ceux vers
un int -- et l'intérêt de « class Foo ; », c'est bien de pouvoir
déclarer un « Foo* ».
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger
de montrer une définition. Dans $7.1.3.3, Je note aussi que le
diagnostic indiqué de «typedef int complex;» (suite à class
complex { /* ... */};) est une redéfinition (alors que typedef
fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration
définit bien le symbole (sinon l'objet, le type ou la fonction
que le symbole désigne).
En fait, ce serait pas mal qu'un «typedef-name» soit un
«class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse
pas implémenter avec les techniques courantes.
Je suppose que cela serait source de problèmes, mais, si c'est
bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le
name-mangling:
class Foo ;
void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ...
typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose comme
ça...
{
}
--
James Kanze kanze.james@neuf.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
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Note bien qu'on ne pourrait pas permettre une utilisation de Foo entre les deux, parce que rien ne garantit que la taille et le format des pointeurs vers une classe sont identiques à ceux vers un int -- et l'intérêt de « class Foo ; », c'est bien de pouvoir déclarer un « Foo* ».
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger de montrer une définition. Dans $7.1.3.3, Je note aussi que le diagnostic indiqué de «typedef int complex;» (suite à class complex { /* ... */};) est une redéfinition (alors que typedef fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration définit bien le symbole (sinon l'objet, le type ou la fonction que le symbole désigne).
En fait, ce serait pas mal qu'un «typedef-name» soit un «class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse pas implémenter avec les techniques courantes.
Je suppose que cela serait source de problèmes, mais, si c'est bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le name-mangling:
class Foo ; void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ... typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose comme ça... { }
-- James Kanze 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
Fabien LE LEZ
On Sat, 10 Jun 2006 22:24:57 +0200, James Kanze :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais j'aimerais bien pouvoir faire :
// A.h
class A { // Un truc immense };
// X.h
class B;
class X { B *ptr; };
// Jusque-là, rien que du classique...
// X.cpp
#include "X.h" #include "A.h"
typedef A B; // Pas possible malheureusement
On Sat, 10 Jun 2006 22:24:57 +0200, James Kanze <kanze.james@neuf.fr>:
class Foo;
typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui
pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais
j'aimerais bien pouvoir faire :
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais j'aimerais bien pouvoir faire :
// A.h
class A { // Un truc immense };
// X.h
class B;
class X { B *ptr; };
// Jusque-là, rien que du classique...
// X.cpp
#include "X.h" #include "A.h"
typedef A B; // Pas possible malheureusement
Serge Paccalin
Le dimanche 11 juin 2006 à 08:58:40, Fabien LE LEZ a écrit dans fr.comp.lang.c++ :
On Sat, 10 Jun 2006 22:24:57 +0200, James Kanze :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais j'aimerais bien pouvoir faire :
// A.h
class A { // Un truc immense };
// X.h
class B;
class X { B *ptr; };
// Jusque-là, rien que du classique...
// X.cpp
#include "X.h" #include "A.h"
typedef A B; // Pas possible malheureusement
On peut obtenir un truc de ce genre avec les templates :
// A.h -- inchangé
// X.h template <typename B> class X { B *ptr; };
// X.cpp
#include "X.h" #include "A.h"
// Instancier X<A>, c'est possible
-- ___________ 11/06/2006 09:38:59 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Pour bien répondre avec Google, ne pas cliquer -'(__) « Répondre », mais « Afficher les options », _/___(_) puis cliquer « Répondre » (parmi les options).
Le dimanche 11 juin 2006 à 08:58:40, Fabien LE LEZ a écrit dans
fr.comp.lang.c++ :
On Sat, 10 Jun 2006 22:24:57 +0200, James Kanze <kanze.james@neuf.fr>:
class Foo;
typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui
pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais
j'aimerais bien pouvoir faire :
// A.h
class A
{
// Un truc immense
};
// X.h
class B;
class X
{
B *ptr;
};
// Jusque-là, rien que du classique...
// X.cpp
#include "X.h"
#include "A.h"
typedef A B; // Pas possible malheureusement
On peut obtenir un truc de ce genre avec les templates :
// A.h -- inchangé
// X.h
template <typename B>
class X
{
B *ptr;
};
// X.cpp
#include "X.h"
#include "A.h"
// Instancier X<A>, c'est possible
--
___________ 11/06/2006 09:38:59
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Pour bien répondre avec Google, ne pas cliquer
-'(__) « Répondre », mais « Afficher les options »,
_/___(_) puis cliquer « Répondre » (parmi les options).
Le dimanche 11 juin 2006 à 08:58:40, Fabien LE LEZ a écrit dans fr.comp.lang.c++ :
On Sat, 10 Jun 2006 22:24:57 +0200, James Kanze :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Je ne connaissais pas le problème de taille de pointeur, mais j'aimerais bien pouvoir faire :
// A.h
class A { // Un truc immense };
// X.h
class B;
class X { B *ptr; };
// Jusque-là, rien que du classique...
// X.cpp
#include "X.h" #include "A.h"
typedef A B; // Pas possible malheureusement
On peut obtenir un truc de ce genre avec les templates :
// A.h -- inchangé
// X.h template <typename B> class X { B *ptr; };
// X.cpp
#include "X.h" #include "A.h"
// Instancier X<A>, c'est possible
-- ___________ 11/06/2006 09:38:59 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Pour bien répondre avec Google, ne pas cliquer -'(__) « Répondre », mais « Afficher les options », _/___(_) puis cliquer « Répondre » (parmi les options).
fabien.chene
James Kanze writes:
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger de montrer une définition. Dans $7.1.3.3, Je note aussi que le diagnostic indiqué de «typedef int complex;» (suite à class complex { /* ... */};) est une redéfinition (alors que typedef fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration définit bien le symbole (sinon l'objet, le type ou la fonction que le symbole désigne).
Je crois que je suis confus avec ça : « Une déclaration définit un symbole ». La norme en parle-t'elle ?
En fait, ce serait pas mal qu'un «typedef-name» soit un «class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse pas implémenter avec les techniques courantes.
D'accord. Sinon, je crois que la solution actuelle consiste à faire une classe wrapper qui contient un operateur de conversion vers le type en question, et un constructeur non explicit du type en question -- un BOOST_STRONG_TYPEDEF en fait. On a alors la possibilité de déclarer ce type avec le mot clé class.
Je vais jeter un oeil dans les papiers sur «opaque typedef». Il y a surement des choses intéressantes.
Je suppose que cela serait source de problèmes, mais, si c'est bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le name-mangling:
class Foo ; void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ... typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose comme ça... { }
Effectivement, si « Une déclaration définit un symbole », et que le name-mangling vient s'en méler, je comprends la limitation.
-- Fab
James Kanze <kanze.james@neuf.fr> writes:
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme
a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo;
typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui
pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger
de montrer une définition. Dans $7.1.3.3, Je note aussi que le
diagnostic indiqué de «typedef int complex;» (suite à class
complex { /* ... */};) est une redéfinition (alors que typedef
fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration
définit bien le symbole (sinon l'objet, le type ou la fonction
que le symbole désigne).
Je crois que je suis confus avec ça : « Une déclaration définit un
symbole ». La norme en parle-t'elle ?
En fait, ce serait pas mal qu'un «typedef-name» soit un
«class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse
pas implémenter avec les techniques courantes.
D'accord. Sinon, je crois que la solution actuelle consiste à faire
une classe wrapper qui contient un operateur de conversion vers le
type en question, et un constructeur non explicit du type en question
-- un BOOST_STRONG_TYPEDEF en fait. On a alors la possibilité de
déclarer ce type avec le mot clé class.
Je vais jeter un oeil dans les papiers sur «opaque typedef». Il y a
surement des choses intéressantes.
Je suppose que cela serait source de problèmes, mais, si c'est
bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le
name-mangling:
class Foo ;
void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ...
typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose
comme ça...
{
}
Effectivement, si « Une déclaration définit un symbole », et que le
name-mangling vient s'en méler, je comprends la limitation.
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
A noter que l'exemple illustratif de $7.1.3.3 se sent obliger de montrer une définition. Dans $7.1.3.3, Je note aussi que le diagnostic indiqué de «typedef int complex;» (suite à class complex { /* ... */};) est une redéfinition (alors que typedef fait une déclaration).
Le typedef est bien une déclaration, mais même une déclaration définit bien le symbole (sinon l'objet, le type ou la fonction que le symbole désigne).
Je crois que je suis confus avec ça : « Une déclaration définit un symbole ». La norme en parle-t'elle ?
En fait, ce serait pas mal qu'un «typedef-name» soit un «class-name», même s'il ne nommme pas une classe.
Ce ne serait pas mal, en effet. Malheureusement, ça ne se laisse pas implémenter avec les techniques courantes.
D'accord. Sinon, je crois que la solution actuelle consiste à faire une classe wrapper qui contient un operateur de conversion vers le type en question, et un constructeur non explicit du type en question -- un BOOST_STRONG_TYPEDEF en fait. On a alors la possibilité de déclarer ce type avec le mot clé class.
Je vais jeter un oeil dans les papiers sur «opaque typedef». Il y a surement des choses intéressantes.
Je suppose que cela serait source de problèmes, mais, si c'est bien le cas, j'avoue ne pas le(s) voir du premier coup d'oeil.
Considère l'implémentation classique des fonctions, avec le name-mangling:
class Foo ; void f( Foo* ) ; // définit le nom __1f_3Foo, par exemple...
// ... typedef int Foo ;
void f( Foo* pi ) // le nom ici est __1f_i, ou quelque chose comme ça... { }
Effectivement, si « Une déclaration définit un symbole », et que le name-mangling vient s'en méler, je comprends la limitation.
typedef ne déclare rien, sinon une nouvelle orthographe pour un type.
§3.1.3 dit que c'est une déclaration.
C'est une formalité de la norme. Elle a la syntaxe d'une déclaration ; elle en est une. Dire que c'est une déclaration dans ce sens-là ne dit pas grand chose -- elle catégorise le type d'instruction. Quoique...
Comme toute déclaration, elle « définit » un (ou plusieurs) symboles -- définir, dans le sens qu'elle les fait connaître au compilateur. (Voir §3.1/1 : « A declaration *introduces* names into a translation unit, or redeclares names introduced by previous declarations. A declaration specifies the interpretations and attributres of these names. ») Ensuite, §3.3/4 précise que dans une portée donnée, il faut qu'un symbole donné réfère toujours à la même chose, à deux exceptions près : le surcharge des fonctions, et un hack de compatibilité C. (Note que ça ne concerne que les symboles déclarés par des déclarations. Il peut y avoir une étiquette avec le même nom. Et évidement, le préprocesseur a ses propres règles à lui.)
Note bien que la norme donne une signification particulière très précise aux mots « déclaration » et « définition ». Une déclaration définit un symbole, plus ou moins complètement. Une définition est une déclaration qui définit complètement un type, un objet ou une fonction. Typedef est une déclaration seulement, parce que malgré son nom, il ne définit pas de type ; il ne fait que déclarer que le nom en question désigne ce type (qui doit être déjà connu, au moins du nom, du compilateur -- il n'y a pas de déclaration anticipée du typedef).
Ce qui s'est passé dans l'exemple initial, donc, c'est que le même symbole a été « introduit » deux foix dans la même porté e, avec deux significations différentes. Sans que les deux définitions tombent dans un des cas d'exception où c'est permis.
-- James Kanze GABI Software 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
Fabien CHÊNE wrote:
Fabien LE LEZ <gramster@gramster.com> writes:
typedef ne déclare rien, sinon une nouvelle orthographe pour
un type.
§3.1.3 dit que c'est une déclaration.
C'est une formalité de la norme. Elle a la syntaxe d'une
déclaration ; elle en est une. Dire que c'est une déclaration
dans ce sens-là ne dit pas grand chose -- elle catégorise le
type d'instruction. Quoique...
Comme toute déclaration, elle « définit » un (ou plusieurs)
symboles -- définir, dans le sens qu'elle les fait connaître au
compilateur. (Voir §3.1/1 : « A declaration *introduces* names
into a translation unit, or redeclares names introduced by
previous declarations. A declaration specifies the
interpretations and attributres of these names. ») Ensuite,
§3.3/4 précise que dans une portée donnée, il faut qu'un symbole
donné réfère toujours à la même chose, à deux exceptions près :
le surcharge des fonctions, et un hack de compatibilité C. (Note
que ça ne concerne que les symboles déclarés par des
déclarations. Il peut y avoir une étiquette avec le même nom. Et
évidement, le préprocesseur a ses propres règles à lui.)
Note bien que la norme donne une signification particulière très
précise aux mots « déclaration » et « définition ». Une
déclaration définit un symbole, plus ou moins complètement. Une
définition est une déclaration qui définit complètement un type,
un objet ou une fonction. Typedef est une déclaration seulement,
parce que malgré son nom, il ne définit pas de type ; il ne fait
que déclarer que le nom en question désigne ce type (qui doit
être déjà connu, au moins du nom, du compilateur -- il n'y a pas
de déclaration anticipée du typedef).
Ce qui s'est passé dans l'exemple initial, donc, c'est que le
même symbole a été « introduit » deux foix dans la même porté e,
avec deux significations différentes. Sans que les deux
définitions tombent dans un des cas d'exception où c'est permis.
--
James Kanze GABI Software
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
typedef ne déclare rien, sinon une nouvelle orthographe pour un type.
§3.1.3 dit que c'est une déclaration.
C'est une formalité de la norme. Elle a la syntaxe d'une déclaration ; elle en est une. Dire que c'est une déclaration dans ce sens-là ne dit pas grand chose -- elle catégorise le type d'instruction. Quoique...
Comme toute déclaration, elle « définit » un (ou plusieurs) symboles -- définir, dans le sens qu'elle les fait connaître au compilateur. (Voir §3.1/1 : « A declaration *introduces* names into a translation unit, or redeclares names introduced by previous declarations. A declaration specifies the interpretations and attributres of these names. ») Ensuite, §3.3/4 précise que dans une portée donnée, il faut qu'un symbole donné réfère toujours à la même chose, à deux exceptions près : le surcharge des fonctions, et un hack de compatibilité C. (Note que ça ne concerne que les symboles déclarés par des déclarations. Il peut y avoir une étiquette avec le même nom. Et évidement, le préprocesseur a ses propres règles à lui.)
Note bien que la norme donne une signification particulière très précise aux mots « déclaration » et « définition ». Une déclaration définit un symbole, plus ou moins complètement. Une définition est une déclaration qui définit complètement un type, un objet ou une fonction. Typedef est une déclaration seulement, parce que malgré son nom, il ne définit pas de type ; il ne fait que déclarer que le nom en question désigne ce type (qui doit être déjà connu, au moins du nom, du compilateur -- il n'y a pas de déclaration anticipée du typedef).
Ce qui s'est passé dans l'exemple initial, donc, c'est que le même symbole a été « introduit » deux foix dans la même porté e, avec deux significations différentes. Sans que les deux définitions tombent dans un des cas d'exception où c'est permis.
-- James Kanze GABI Software 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
Fabien LE LEZ
On Mon, 12 Jun 2006 22:20:43 +0200, (Fabien CHÊNE):
Dans un environnement de compilation -- que je subis -- où le réseau est lent, et les machines bien gonflées en CPU et RAM, on arrive à des records de part de temps de préprocessing; jusqu'à 80% du temps de compilation passé en préprocessing :-(
C'est peut-être que le système de compilation est mal pensé ? Peut-être faudrait-il récupérer tous les fichiers en local (avec rsync par exemple) avant même de commencer la compilation ?
On Mon, 12 Jun 2006 22:20:43 +0200, fabien.chene@gmail.com (Fabien
CHÊNE):
Dans un environnement de
compilation -- que je subis -- où le réseau est lent, et les machines
bien gonflées en CPU et RAM, on arrive à des records de part de temps
de préprocessing; jusqu'à 80% du temps de compilation passé en
préprocessing :-(
C'est peut-être que le système de compilation est mal pensé ?
Peut-être faudrait-il récupérer tous les fichiers en local (avec rsync
par exemple) avant même de commencer la compilation ?
On Mon, 12 Jun 2006 22:20:43 +0200, (Fabien CHÊNE):
Dans un environnement de compilation -- que je subis -- où le réseau est lent, et les machines bien gonflées en CPU et RAM, on arrive à des records de part de temps de préprocessing; jusqu'à 80% du temps de compilation passé en préprocessing :-(
C'est peut-être que le système de compilation est mal pensé ? Peut-être faudrait-il récupérer tous les fichiers en local (avec rsync par exemple) avant même de commencer la compilation ?
fabien.chene
"kanze" writes:
Fabien CHÊNE wrote:
James Kanze writes:
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
Je crois au contraire que le supporter augmenterait les temps de compilation, nettement,
Tu l'évoques à un autre endroit dans ce fil, ce serait une sorte de déclaration anticipée d'un typedef. Dans un environnement de compilation -- que je subis -- où le réseau est lent, et les machines bien gonflées en CPU et RAM, on arrive à des records de part de temps de préprocessing; jusqu'à 80% du temps de compilation passé en préprocessing :-( Dans cet environnemnt, la possibilité de faire « une déclaration anticipée de typedef » réduirait de beaucoup le temps de compilation.
et qu'il pourrait aussi augmenter les dépendances du compilateur.
En quoi ça consiste, une dépendance du compilateur ?
Grosso modo, il faudrait traiter toute utilisation de Foo, tant qu'on n'a pas vue sa définition, comme un template.
class Foo ; // Supposons que Foo pourrait être // défini plus tard comme int, ou char.
class B { Foo * ptr ; } ; // Interne, c'est comme si B était un template, // parce que je ne connais pas encore la taille de ptr.
void f( Foo* ptr ) ; // Template aussi, parce que je ne connais pas encore // comment passer ptr comme paramètre.
Ensuite, ça s'enchaîne tant que je ne connais pas ce que c'est Foo.
Effectivement.
Je crois que je suis confus avec ça : « Une déclaration définit un symbole ». La norme en parle-t'elle ?
J'essayais d'utiliser un peu le langage courant. La norme s'efforce d'être précise. Pour le faire, elle donne une signification particulière à certains mots. Donc, quand la norme parle de « définition », c'est toujours d'un type, d'un objet, ou d'une fonction. Une déclaration « introduit » un symbole dans une portée donnée. Mais évidemment, en l'introduisant, elle précise plus ou moins sa signification (dans cette portée, évidemment). Donc, « class Foo ; » est une déclaration qui introduit le symbole « Foo » dans sa portée ; elle dit en plus que « Foo » est le nom d'un type de classe, qui n'est pas une union. De même, " typedef int Foo ; » introduit le nom Foo dans la portée, en disant que c'est un synonym pour int. (Note aussi que dans le cas de typedef, le symbole doit être un synonym ; il ne peut pas être le nom même d'un type. À quelques exceptions très spéciales pour la compatibilité C.) Tout ce que je voulais dire, c'est qu'avant « typedef int Foo ; », le compilateur ne savait pas ce que signifiait le symbole « Foo », et après, il le sait. Dans le langage courant, je considèrerais ça comme une définition du symbole Foo. Dans le langage de la norme, non, parce que l'utilisation du mot « définition » ici pourrait préter à l'ambiguïté avec la définition d'un type, d'un objet ou d'une fonction.
(Merci pour la qualité de cette réponse)
-- Fab
"kanze" <kanze@gabi-soft.fr> writes:
Fabien CHÊNE wrote:
James Kanze <kanze.james@neuf.fr> writes:
Fabien CHÊNE wrote:
Une question qui me tarabuste, Qu'est-ce qui a motivé la
norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo;
typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui
pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
Je crois au contraire que le supporter augmenterait les temps de
compilation, nettement,
Tu l'évoques à un autre endroit dans ce fil, ce serait une sorte de
déclaration anticipée d'un typedef. Dans un environnement de
compilation -- que je subis -- où le réseau est lent, et les machines
bien gonflées en CPU et RAM, on arrive à des records de part de temps
de préprocessing; jusqu'à 80% du temps de compilation passé en
préprocessing :-(
Dans cet environnemnt, la possibilité de faire « une déclaration
anticipée de typedef » réduirait de beaucoup le temps de compilation.
et qu'il pourrait aussi augmenter les dépendances du compilateur.
En quoi ça consiste, une dépendance du compilateur ?
Grosso modo, il faudrait traiter
toute utilisation de Foo, tant qu'on n'a pas vue sa définition,
comme un template.
class Foo ; // Supposons que Foo pourrait être
// défini plus tard comme int, ou char.
class B
{
Foo * ptr ;
} ;
// Interne, c'est comme si B était un template,
// parce que je ne connais pas encore la taille de ptr.
void f( Foo* ptr ) ;
// Template aussi, parce que je ne connais pas encore
// comment passer ptr comme paramètre.
Ensuite, ça s'enchaîne tant que je ne connais pas ce que c'est
Foo.
Effectivement.
Je crois que je suis confus avec ça : « Une déclaration
définit un symbole ». La norme en parle-t'elle ?
J'essayais d'utiliser un peu le langage courant. La norme
s'efforce d'être précise. Pour le faire, elle donne une
signification particulière à certains mots. Donc, quand la norme
parle de « définition », c'est toujours d'un type, d'un objet,
ou d'une fonction. Une déclaration « introduit » un symbole dans
une portée donnée. Mais évidemment, en l'introduisant, elle
précise plus ou moins sa signification (dans cette portée,
évidemment). Donc, « class Foo ; » est une déclaration qui
introduit le symbole « Foo » dans sa portée ; elle dit en plus
que « Foo » est le nom d'un type de classe, qui n'est pas une
union. De même, " typedef int Foo ; » introduit le nom Foo dans
la portée, en disant que c'est un synonym pour int. (Note aussi
que dans le cas de typedef, le symbole doit être un synonym ; il
ne peut pas être le nom même d'un type. À quelques exceptions
très spéciales pour la compatibilité C.) Tout ce que je voulais
dire, c'est qu'avant « typedef int Foo ; », le compilateur ne
savait pas ce que signifiait le symbole « Foo », et après, il le
sait. Dans le langage courant, je considèrerais ça comme une
définition du symbole Foo. Dans le langage de la norme, non,
parce que l'utilisation du mot « définition » ici pourrait
préter à l'ambiguïté avec la définition d'un type, d'un objet ou
d'une fonction.
Une question qui me tarabuste, Qu'est-ce qui a motivé la norme a déclarer ce code illégal ? (selon $7.1.3.3) :
class Foo; typedef int Foo;
Je me poserais plutôt la question inverse : qu'est-ce qui pouvait être l'intérêt de le permettre ?
Réduire les dépendances, et les temps de compilation probablement.
Je crois au contraire que le supporter augmenterait les temps de compilation, nettement,
Tu l'évoques à un autre endroit dans ce fil, ce serait une sorte de déclaration anticipée d'un typedef. Dans un environnement de compilation -- que je subis -- où le réseau est lent, et les machines bien gonflées en CPU et RAM, on arrive à des records de part de temps de préprocessing; jusqu'à 80% du temps de compilation passé en préprocessing :-( Dans cet environnemnt, la possibilité de faire « une déclaration anticipée de typedef » réduirait de beaucoup le temps de compilation.
et qu'il pourrait aussi augmenter les dépendances du compilateur.
En quoi ça consiste, une dépendance du compilateur ?
Grosso modo, il faudrait traiter toute utilisation de Foo, tant qu'on n'a pas vue sa définition, comme un template.
class Foo ; // Supposons que Foo pourrait être // défini plus tard comme int, ou char.
class B { Foo * ptr ; } ; // Interne, c'est comme si B était un template, // parce que je ne connais pas encore la taille de ptr.
void f( Foo* ptr ) ; // Template aussi, parce que je ne connais pas encore // comment passer ptr comme paramètre.
Ensuite, ça s'enchaîne tant que je ne connais pas ce que c'est Foo.
Effectivement.
Je crois que je suis confus avec ça : « Une déclaration définit un symbole ». La norme en parle-t'elle ?
J'essayais d'utiliser un peu le langage courant. La norme s'efforce d'être précise. Pour le faire, elle donne une signification particulière à certains mots. Donc, quand la norme parle de « définition », c'est toujours d'un type, d'un objet, ou d'une fonction. Une déclaration « introduit » un symbole dans une portée donnée. Mais évidemment, en l'introduisant, elle précise plus ou moins sa signification (dans cette portée, évidemment). Donc, « class Foo ; » est une déclaration qui introduit le symbole « Foo » dans sa portée ; elle dit en plus que « Foo » est le nom d'un type de classe, qui n'est pas une union. De même, " typedef int Foo ; » introduit le nom Foo dans la portée, en disant que c'est un synonym pour int. (Note aussi que dans le cas de typedef, le symbole doit être un synonym ; il ne peut pas être le nom même d'un type. À quelques exceptions très spéciales pour la compatibilité C.) Tout ce que je voulais dire, c'est qu'avant « typedef int Foo ; », le compilateur ne savait pas ce que signifiait le symbole « Foo », et après, il le sait. Dans le langage courant, je considèrerais ça comme une définition du symbole Foo. Dans le langage de la norme, non, parce que l'utilisation du mot « définition » ici pourrait préter à l'ambiguïté avec la définition d'un type, d'un objet ou d'une fonction.