| View previous topic :: View next topic |
| Author |
Message |
Gabriel Dos Reis Guest
|
Posted: Fri May 28, 2004 3:56 pm Post subject: Re: Pointeur de fonctions... |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| Quote: | Quelqu'un peut-il m'expliquer pourquoi ceci
typedef void (*funcType)();
void foo(funcType);
void bar();
void test() {
foo(*******bar);
}
passe (au moins avec Como et Forte).
|
Parce qu'un jour le comité C a décidé que si tu as un pointeur pf vers
une function, tu peux juste dire pf() au lieu de (*pf)() --
contrairement aux enseignments de K+R. L'idée était alors de dire
qu'un désignateur de fonction, sauf quelques situations particulières,
est un pointeur vers une fonction. Mais comme *pf est aussi
un designateur de fonction, tu peux dire **pf, ainsi de suite.
Bref, c'est stupide mais il faut vivre avec.
6.3.2.1 Lvalues, arrays, and function designators
[...]
[#4] A function designator is an expression that has
function type. Except when it is the operand of the sizeof
operator54) or the unary & operator, a function designator
with type ``function returning type'' is converted to an
expression that has type ``pointer to function returning
type''.
-- Gaby
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
Alexandre Guest
|
Posted: Fri May 28, 2004 5:37 pm Post subject: Re: Pointeur de fonctions... |
|
|
bonjour,
| Quote: | Quelqu'un peut-il m'expliquer pourquoi ceci
typedef void (*funcType)();
void foo(funcType);
void bar();
void test() {
foo(*******bar);
}
passe (au moins avec Como et Forte).
|
je pense parce que l'opérateur d'indirection (*) n'a pas d'effet réel sur un
pointeur de fonction. Dans ton cas, bar représente l'adresse de la fonction,
&bar aussi, et je suppute que *bar aussi... Je pense donc que les écritures
foo(bar)
foo(&bar)
foo(*bar)
sont équivalentes.
|
|
| Back to top |
|
 |
Horst Kraemer Guest
|
Posted: Fri May 28, 2004 7:57 pm Post subject: Re: Pointeur de fonctions... |
|
|
On 28 May 2004 18:06:56 +0200, Jean-Marc Bourguet <jm (AT) bourguet (DOT) org>
wrote:
| Quote: |
Quelqu'un peut-il m'expliquer pourquoi ceci
typedef void (*funcType)();
void foo(funcType);
void bar();
void test() {
foo(*******bar);
}
passe (au moins avec Como et Forte).
A+
|
D'après la norme du langage C toute expression qui désigne une
fonction (c.a.d. une lvalue du type fonction) à l'exception des cas ou
l'opérateur & est appliqué à la fonction - est convertie
automatiquement en pointeur vers fonction qui pointe vers cette
fonction, c.a.d. la fonction est convertie automatiquement en sa
propre adresse.
D'après la norme du langage C++ toute expression qui désigne une
fonction à l'exception des cas ou l'opérateur & ou l'opérateur d'appel
() est appliqué à la fonction est convertie automatiquement en
pointeur vers fonction qui pointe vers cette fonction.
Cela veut dire que dans les deux langages l'expression
*****bar
comme argument d'une fonction subit les conversions implicites
intercalées suivantes
&*&*&*&*&*&bar
_avant_ d'étre passée.
Donc le type de l'expression *****bar est en fait les type de
l'expression &*&*&*&*&*&bar - et ce type est le même que le type de
&bar. Les * répétés n'ont donc aucun effet parce que les résultat de
chaque * qui produit une expression du type 'fonction' est reconverti
immédiatement en pointeur vers fonction.
En C, l'expression 'bar' est *toujours* convertie automatiquement en
pointeur sauf dans l'expresion &bar - même dans l'expression bar(). La
raison est que l'opérande de l'opérateur () d'appel doit avoir le type
'pointeur vers fonction' en C. En C++ l'opérande de l'opérateur ()
peut être une fonction _ou_ un pointeur vers fonction. Donc
formellement en C++ 'bar' n'est pas convertie en pointeur dans
l'expression bar() - mais cette différence formelle entre C et C++ ne
ne se voit pas.
Le résultat est que dans les deux langages on peut appeler la fonction
'bar' après les définitions suivantes
void bar(void) {}
void (*f) (void) = bar; /* ou = &bar */
par chaqu'une des expressions suivantes:
bar()
Légal en C++ parce que () accepte une fonction et légal en C parce que
() n'accepte que des pointeurs vers fonctions mais 'bar' est converti
automatiquement en son adresse &bar.
(*bar)();
*bar est légal dans les deux langages bien que bar soit une fonction
parce que bar est converti automatiquement en &bar avant l'application
de l'opérateur *. En C *bar (c.a.d. *&bar) est reconverti en &*bar
(c.a.d. en &*&bar) avant l'appel et en C++ l'opérateur accepte la
fonction *bar (*&bar).
(**bar)();
(***bar)();
...
Voir l'explication plus haut
...
(&bar)()
Légal en C parce que &bar a le type exact qu'il faut pour un appel.
Légal en C++ parce l'opérateur () accepte ou bien une fonction ou bien
un pointeur.
(&&bar)()
Erreur dans les deux langages ;-)
...
f();
f a le bon type en C et un des bons types en C++
(*f)();
En C *f est reconconverti en &*f pour l'appel et en C++ *f a un des
bons types pour l'appel.
(**f)();
...
voir plus haut.
--
Horst
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Sat May 29, 2004 11:43 am Post subject: Re: Pointeur de fonctions... |
|
|
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> writes:
| Quote: | Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| Quelqu'un peut-il m'expliquer pourquoi ceci
|
| typedef void (*funcType)();
|
| void foo(funcType);
| void bar();
|
| void test() {
| foo(*******bar);
| }
|
| passe (au moins avec Como et Forte).
Parce qu'un jour le comité C a décidé que si tu as un pointeur pf vers
une function, tu peux juste dire pf() au lieu de (*pf)()
--
|
Je suppose que tu voulais écrire pf = f au lieu de pf = &f.
C'est bien ce à quoi je pensais mais la conséquence est
amusante... Enfin je suppose que nous sommes d'accord que
l'écriture la plus claire est
foo(&bar);
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
|
|
| Back to top |
|
 |
Loïc Joly Guest
|
Posted: Sat May 29, 2004 12:10 pm Post subject: Re: Pointeur de fonctions... |
|
|
Jean-Marc Bourguet wrote:
| Quote: | Enfin je suppose que nous sommes d'accord que
l'écriture la plus claire est
foo(&bar);
|
Tout comme le plus naturel est d'écrire :
cout << "Hello world!" << &endl;
;p ?
--
Loïc
|
|
| Back to top |
|
 |
Michel Michaud Guest
|
Posted: Sat May 29, 2004 2:07 pm Post subject: Re: Pointeur de fonctions... |
|
|
Dans news:j1t99c.tg.ln (AT) news (DOT) bourguet.org, Jean-Marc
Bourguet <jm (AT) bourguet (DOT) org> a écrit :
| Quote: | Enfin je suppose que nous sommes d'accord que
l'écriture la plus claire est
foo(&bar);
|
Pas pour moi... foo(bar); est la plus claire... On est en
C++ et je ne veux même pas modifié bar... :-)
(mais on ne repartira pas une discussion là-dessus, chacun
a son opinion et je ne voulais simplement pas laisser ton
message passé sans contestation)
--
Michel Michaud [email]mm (AT) gdzid (DOT) com[/email]
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sat May 29, 2004 2:30 pm Post subject: Re: Pointeur de fonctions... |
|
|
Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| Quote: | l'écriture la plus claire est
foo(&bar);
|
Oui. Et c'est ce que Le Père a choisi pour les fonctions membres
non-statiques.
J'ai découvert assez récemment que Core a réussi à encore inventer des
trucs à dormir debout.
typedef void fun_t();
struct A {
fun_t foo; // foo fonction membre non-statique
};
A::foo est de type void (), mais &A::foo est de type
void (A::*)() ; et bien sûr pour rendre le truc plus amusant,
bien que A::foo soit de type void (), on ne peut pas la lier
à une référence de type void (&) -- bien qu'on puisse le
faire avec les autres fonctions de ce type. Groumph.
Cette invention de Core est une décision contraire à une
note explicative de l'ARM. Groumph.
-- Gaby
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
Loïc Joly Guest
|
Posted: Sat May 29, 2004 11:20 pm Post subject: Re: Pointeur de fonctions... |
|
|
Gabriel Dos Reis wrote:
| Quote: | Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> writes:
| l'écriture la plus claire est
| foo(&bar);
Oui. Et c'est ce que Le Père a choisi pour les fonctions membres
non-statiques.
J'ai découvert assez récemment que Core a réussi à encore inventer des
trucs à dormir debout.
|
Ils préparent l'IOC++CC...
--
Loïc
|
|
| Back to top |
|
 |
|