OVH Cloud OVH Cloud

Pointeurs vers fonctions

54 réponses
Avatar
Pierre Maurette
Bonjour,
Mon problème est peut-être plus C que C++, mais je le fais facilement
apparaître avec new[], et de plus c'est la réponse de la norme C++ qui
m'intéresse le plus.
Si on définit une variable pointeur de fonction :
int(*pF)(double, double) = NULL;
on a la facilité d'utiliser ou non, indifféremment, les opérateurrs * et & ,
ou plus exactement on a exceptionnellement la possibilité de les omettre :
int fonct(double x, double y) {return (int)(x * y);}
...
pF = &fonct;
pF = fonct;
...
x = pF(4.0, 2.0);
x = (*pF)(4.0, 2.0);

Question : qu'en dit la norme ? (pas pu trouver)

Si je désire un tableau de fonctions dont la taile sera déterminée à
l'exécution, je dois faire :
int(**pF)(double, double) = NULL;
Ensuite, en C comme en C++ :
int n = 12;
pF = (int(**)(double, double))malloc(n * sizeof(int(*)(double, double)));
x = pF[4](4.0, 2.0);
Pas beau, puisque pF n'a pas le même type dans les deux lignes, mais logique
au vu de ce qui précède.
Passons au new[] :
pF = new (int(*)(double, double))[n];
La famille du Gnou accepte, et le résultat est celui attendu. Chez Borland,
c'est non., conversion de type impossible
Les Gnou interprètent pF en fonction de l'appel de malloc() ou de new[], pas
Borland. Je ne suis pas contre, je préfèrerais même que ne soient pas
autorisées les facilités initiales, donc que le typedef s'impose de
lui-même.
Question : Qu'en dit la norme ? Qui a raison ?

Bien entendu, un typedef s'impose, et tout rentre dans l'ordre.

typedef int(*Fonc_Type)(double, double);
Fonc_Type* pF1;
Fonc_Type* pF2;
int n = 12;
pF1 = (Fonc_Type*) malloc(n * sizeof(Fonc_Type));
pF2 = new Fonc_Type[n];
pF1[5] = f1;
pF2[6] = f2;

Merci pour vous lulières,
Pierre

10 réponses

1 2 3 4 5
Avatar
kanze
Gabriel Dos Reis wrote in message
news:...
writes:

| Ce n'est pas une raison. J'ai écrit de l'assembleur pendant au moins
| dix ans avant de passer aux langages évolués.

Tu comptes le C comme de l'assembleur ou comme un langage évolué.


Langage évolué, bien que je sais que c'est à la limite. Aux années 70,
les seuls langages évolués qu'on trouvaient dans beaucoup de boîtes,
c'était le Fortran ou le Cobol. Et il y a bien de types d'applications
où ces langages ne convenaient pas.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Pierre Maurette
"Gabriel Dos Reis" a écrit dans le message de
news:
writes:

| Ce n'est pas une raison. J'ai écrit de l'assembleur pendant au moins dix
| ans avant de passer aux langages évolués.

Tu comptes le C comme de l'assembleur ou comme un langage évolué.
Peut-on définir un langage évolué comme un langage dans lequel le code objet

généré est entièrement prévisible ? C'est l'idée que je m'en fais, sans
grande conviction.
Donc, tout programme proposant de l'optimisation serait évolué.
MASM et TASM sont non évolués, mais efficaces grâce aux macros. HLA
peut-être évolué. C évolué.
En fait, un compilateur C avec quelques dizaines de milliers de pages de
documentation perdrait son statut de langage évolué. (pour C++, j'y crois
pas). Il doit bien exister sur microcontrôleur des Basic ou C 100%
prévisibles ?
Un langage portable peut-il ne pas être évolué ?
Que dire d'un assembleur portable, qui assemblerait des pseudo-instructions
machines, par exemple à destination d'une machine virtuelle ?
En fait, il semble que "évolué" n'est pas tout ou rien. MASM + une bib
"normale" est "un peu" évolué.
Pierre

Avatar
Gabriel Dos Reis
writes:

| Gabriel Dos Reis wrote in message
| news:...
| > writes:
|
| > | Ce n'est pas une raison. J'ai écrit de l'assembleur pendant au moins
| > | dix ans avant de passer aux langages évolués.
|
| > Tu comptes le C comme de l'assembleur ou comme un langage évolué.
|
| Langage évolué, bien que je sais que c'est à la limite. Aux années 70,
| les seuls langages évolués qu'on trouvaient dans beaucoup de boîtes,
| c'était le Fortran ou le Cobol. Et il y a bien de types d'applications
| où ces langages ne convenaient pas.

La première phrase répond à ma question. Les reste n'a rien à avoir.
Merci.

-- Gaby
Avatar
Gabriel Dos Reis
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> writes:

| "Gabriel Dos Reis" a écrit dans le message de
| news:
| > writes:
| >
| > | Ce n'est pas une raison. J'ai écrit de l'assembleur pendant au moins dix
| > | ans avant de passer aux langages évolués.
| >
| > Tu comptes le C comme de l'assembleur ou comme un langage évolué.
| Peut-on définir un langage évolué comme un langage dans lequel le code objet
| généré est entièrement prévisible ? C'est l'idée que je m'en fais, sans
| grande conviction.

Oh, dans ce thread, James a fait part d'une expérience personnelle --
qui est ce que j'ai citée.
Je voulais l'intégrer avec les autres parts dont j'ai connaissance,
soit parce qu'il les dites publiquement, soit parce qu'il me les a
dites. Et cela n'arrivait pas a rentrer correctement, alors je voulais
savoir, ce que je pouvais virer, ajouter, comprimer ou elargir.
Je n'avais nullement l'intention de me lancer dans un debat de
definition de langage evolué. Juste ce qu'il entendait par langage
evolué suffisait pour moi pour faire face au puzzle que j'avais.

-- Gaby
Avatar
Pierre Maurette
"Gabriel Dos Reis" ...
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> writes:

| "Gabriel Dos Reis" a écrit dans le
message de

| news:
| > writes:
| >
| > | Ce n'est pas une raison. J'ai écrit de l'assembleur pendant au moins
dix

| > | ans avant de passer aux langages évolués.
| >
| > Tu comptes le C comme de l'assembleur ou comme un langage évolué.
| Peut-on définir un langage évolué comme un langage dans lequel le code
objet

| généré est entièrement prévisible ? C'est l'idée que je m'en fais, sans
| grande conviction.

Oh, dans ce thread, James a fait part d'une expérience personnelle --
qui est ce que j'ai citée.
Je voulais l'intégrer avec les autres parts dont j'ai connaissance,
soit parce qu'il les dites publiquement, soit parce qu'il me les a
dites. Et cela n'arrivait pas a rentrer correctement, alors je voulais
savoir, ce que je pouvais virer, ajouter, comprimer ou elargir.
Je n'avais nullement l'intention de me lancer dans un debat de
definition de langage evolué. Juste ce qu'il entendait par langage
evolué suffisait pour moi pour faire face au puzzle que j'avais.


?

Pierre

Avatar
Michel Michaud
Dans news:, Gabriel Dos
"Michel Michaud" writes:

Dans news:,
et dans les faits, j'écris toujours (*pF)( 4.0, 2.0 ). Mais ça me


Même dans les fonctions template acceptant indifféremment un
pointeur sur une fonction ou un objet fonction ? On ne peut
pas s'en sortir : en C++, plus qu'en C (!!!), on a besoin de
la possibilité de ne pas déréférencer explicitement les pointeurs
sur fonction.


Ce n'est pas indispensable. C'est juste une convention ; cette


Si ce n'était pas le cas, est-ce qu'on pourrait s'en sortir en
écrivant deux versions des fonctions : une pour accepter une
fonction, l'autre pour accepter un objet fonction ? Mes
connaissances en méta-programmation m'empêche de voir comment...

Une autre solution serait de ne pas permettre qu'on utilise une
simple fonction comme paramètre... Et une dernière serait de
ne pas faire les classes de fonctions objet pour permettre la
syntaxe directe des appels, mais plutôt passer par un
« déréférencement » explicite comme pour les pointeurs sur
fonctions...

convention est problablement basée sur l'observation qu'il y a pas
mal de pratique où les gens ne déréferencent pas directement les
pointeurs sur fonction. Cela réflète probablement aussi la
culture/pratique des auteurs de la STL.


J'ai l'impression que ça reflète aussi les idées originales de
Ritchie (sinon pourquoi est-ce permis)...

(En fait, je me demande si, un jour, on ne trouvera
pas que c'est une erreur que ce ne soit pas le cas pour les
pointeurs sur fonction membre, d'autant plus que ça semble être
une limitation tout à fait gratuite qui n'apporte rien de
particulier.)


La dernière fois que j'ai posé la question à qui de droit (cela
devait être en 1998), la réponse était qu'il préférait que les gens
soient plus explicites en ce qui concerne les histoires de type --
si tu regardes bien, en fait tu remarqueras que la syntaxe est une
extension simple et direct de la syntaxe K+R.


Bien sûr, mais seulement celle qui demande le déréférencement
explicite.

Et puis, un pointeur sur une fonction-membre non-statique est une
bête vraiment différente des pointeurs sur fonctions ordinaires ou


Tout à fait, mais si on décide de permettre une « syntaxe [qui] est
une extension simple et direct de la syntaxe K+R », pourquoi on le
fait à moitié ?

Mon interrogation est simplement ceci : peut-être par hasard, il
s'est trouvé un intérêt pour la syntaxe pF(param) qui permet
d'utiliser indifféremment un pointeur sur fonction ou un objet
fonction. Considérant que certains compilateurs acceptent la même
syntaxe « simplifiée » pour les pointeurs sur fonctions membres
(semble-t-il sans difficulté ou ambiguïté particulière), je
m'interroge sur la sagesse d'interdire une syntaxe qui pourrait
s'avérer utile un jour (il me semble qu'en C++, on laisse souvent,
ailleurs, la chance au coureur)... En fait, tiens, est-ce qu'il y
a un problème réel à permettre l'autre syntaxe, ou est-ce qu'on
veut simplement choisir pour le programmeur comment il peut
faire les choses ? Si c'est le deuxième choix, il ne me paraît
pas tellement dans l'esprit C ou C++...

des objets fonctionnels (sur un plan plus conceptuel). Ce qui serait
proche d'un objet fonctionnel, ce serait ce que M$ appelle
« bound-pointer », i.e. un machin qui a déjà lié la valeur de «
this » dans un « pseudo pointeur sur fonction membre ». E.g.

object.*pmf

où « object » désigne un objet et « pmf » est un pointeur sur
fonction membre non-statique.


J'avoue ne pas comprendre où tu veux en venir, là.

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/



Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

| Dans news:, Gabriel Dos
| > "Michel Michaud" writes:
| >
| >> Dans news:,
| >>> et dans les faits, j'écris toujours (*pF)( 4.0, 2.0 ). Mais ça me
| >>
| >> Même dans les fonctions template acceptant indifféremment un
| >> pointeur sur une fonction ou un objet fonction ? On ne peut
| >> pas s'en sortir : en C++, plus qu'en C (!!!), on a besoin de
| >> la possibilité de ne pas déréférencer explicitement les pointeurs
| >> sur fonction.
| >
| > Ce n'est pas indispensable. C'est juste une convention ; cette
|
| Si ce n'était pas le cas, est-ce qu'on pourrait s'en sortir en
| écrivant deux versions des fonctions : une pour accepter une
| fonction, l'autre pour accepter un objet fonction ? Mes
| connaissances en méta-programmation m'empêche de voir comment...

Je crois que c'est possible -- même si je n'en vois pas beaucoup
l'utilité. Il suffit de combiner l'infame enable_if<> avec l'un des
traits is_function<>.

| Une autre solution serait de ne pas permettre qu'on utilise une
| simple fonction comme paramètre... Et une dernière serait de
| ne pas faire les classes de fonctions objet pour permettre la
| syntaxe directe des appels, mais plutôt passer par un
| « déréférencement » explicite comme pour les pointeurs sur
| fonctions...
|
| > convention est problablement basée sur l'observation qu'il y a pas
| > mal de pratique où les gens ne déréferencent pas directement les
| > pointeurs sur fonction. Cela réflète probablement aussi la
| > culture/pratique des auteurs de la STL.
|
| J'ai l'impression que ça reflète aussi les idées originales de
| Ritchie (sinon pourquoi est-ce permis)...

???
K+R requiert explicitement le déréférencement ; c'est une des raisons
pour laquelle on a la syntaxe actuelle pour les pointeurs sur fonction
membre.

| >> (En fait, je me demande si, un jour, on ne trouvera
| >> pas que c'est une erreur que ce ne soit pas le cas pour les
| >> pointeurs sur fonction membre, d'autant plus que ça semble être
| >> une limitation tout à fait gratuite qui n'apporte rien de
| >> particulier.)
| >
| > La dernière fois que j'ai posé la question à qui de droit (cela
| > devait être en 1998), la réponse était qu'il préférait que les gens
| > soient plus explicites en ce qui concerne les histoires de type --
| > si tu regardes bien, en fait tu remarqueras que la syntaxe est une
| > extension simple et direct de la syntaxe K+R.
|
| Bien sûr, mais seulement celle qui demande le déréférencement
| explicite.

Oui et c'était la seule tolérée par K+R !

| > Et puis, un pointeur sur une fonction-membre non-statique est une
| > bête vraiment différente des pointeurs sur fonctions ordinaires ou
|
| Tout à fait, mais si on décide de permettre une « syntaxe [qui] est
| une extension simple et direct de la syntaxe K+R », pourquoi on le
| fait à moitié ?

Je ne comprends pas ce que tu veux dire par faire à moitié. La syntaxe
où on peut omettre le « * » est une invention du comité ANSI -- tout
comme la conversion void* -> T*.

[...]

| ailleurs, la chance au coureur)... En fait, tiens, est-ce qu'il y
| a un problème réel à permettre l'autre syntaxe, ou est-ce qu'on
| veut simplement choisir pour le programmeur comment il peut
| faire les choses ?

je ne sais pas. Je n'ai jamais poussé la réflexion au delà de la simple
curiosité du d« tiens, ce n'est pas permis ».

-- Gaby
Avatar
Gabriel Dos Reis
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> writes:

| > Oh, dans ce thread, James a fait part d'une expérience personnelle --
| > qui est ce que j'ai citée.
| > Je voulais l'intégrer avec les autres parts dont j'ai connaissance,
| > soit parce qu'il les dites publiquement, soit parce qu'il me les a
| > dites. Et cela n'arrivait pas a rentrer correctement, alors je voulais
| > savoir, ce que je pouvais virer, ajouter, comprimer ou elargir.
| > Je n'avais nullement l'intention de me lancer dans un debat de
| > definition de langage evolué. Juste ce qu'il entendait par langage
| > evolué suffisait pour moi pour faire face au puzzle que j'avais.
|
| ?

Oui.

-- Gaby
Avatar
Michel Michaud
Dans news:, Gabriel Dos
"Michel Michaud" writes:
J'ai l'impression que ça reflète aussi les idées originales de
Ritchie (sinon pourquoi est-ce permis)...


???
K+R requiert explicitement le déréférencement ; c'est une des
raisons pour laquelle on a la syntaxe actuelle pour les pointeurs
sur fonction membre.


[...]
Bien sûr, mais seulement celle qui demande le déréférencement
explicite.


Oui et c'était la seule tolérée par K+R !


[...]
Je ne comprends pas ce que tu veux dire par faire à moitié. La
syntaxe où on peut omettre le « * » est une invention du comité
ANSI -- tout comme la conversion void* -> T*.


Tu as une meilleure mémoire que moi... Merci :-)

(dans le cas de void, c'était nouveau d'où l'invention, dans
l'autre, il faudrait trouver le « rationale », il me semble
qu'il existe pour ISO C, à moi que tu connaisses la raison de
cette invention ?)

En fait, tiens, est-ce qu'il y
a un problème réel à permettre l'autre syntaxe, ou est-ce qu'on
veut simplement choisir pour le programmeur comment il peut
faire les choses ?


je ne sais pas. Je n'ai jamais poussé la réflexion au delà de la
simple curiosité du d« tiens, ce n'est pas permis ».



La règle K&R originale est bien intéressante historiquement,
mais ANSI/ISO C existait bien avant ISO C++. Ça ne permet pas
de conclure que c'est une bonne/mauvaise chose dans un cas
comme dans l'autre... Mais, comme tu le dis, je crois qu'il
faut parfois arrêter de se poser des questions !

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

| (dans le cas de void, c'était nouveau d'où l'invention, dans
| l'autre, il faudrait trouver le « rationale », il me semble
| qu'il existe pour ISO C, à moi que tu connaisses la raison de
| cette invention ?)

« void » est une invention de BS (surtout pour C with Classes) et
quand il a fait la proposition au comité ANSI, il a bine pris garde de
ne pas inclure le trou void* -> T*. Cependant, le comité ANSI n'a pas
resisté devant l'invention.
En ce qui concerne l'omision de « * » -- qui n'est pas valide en C
K+R -- le comité ANSI a probablement aussi inventé une raison pour cette
invention ; mais je ne saurais te dire exactement quoi à part supiter
« certains programmeurs C trouvent cela plus simple à écrire ».

| >> En fait, tiens, est-ce qu'il y
| >> a un problème réel à permettre l'autre syntaxe, ou est-ce qu'on
| >> veut simplement choisir pour le programmeur comment il peut
| >> faire les choses ?
| >
| > je ne sais pas. Je n'ai jamais poussé la réflexion au delà de la
| > simple curiosité du d« tiens, ce n'est pas permis ».
|
| La règle K&R originale est bien intéressante historiquement,
| mais ANSI/ISO C existait bien avant ISO C++.

oui mais, je ne crois pas que cette invention était quelque chose qui
ait fait unanimité dans la communauté C++ -- surtout chez ceux qui sont
attachés à la notion de type.

| Ça ne permet pas
| de conclure que c'est une bonne/mauvaise chose dans un cas
| comme dans l'autre... Mais, comme tu le dis, je crois qu'il
| faut parfois arrêter de se poser des questions !

:-)

-- Gaby
1 2 3 4 5