OVH Cloud OVH Cloud

Déclaration de pointeurs de fonction

7 réponses
Avatar
Yoxoman
Bonjour à tous.

On déclare un pointeur de fontion vers une fonction void f(int) comme ça
:

void (*p)(int) = f;

et pas comme ça :

void (*)(int) p = f;

Etant donné que le "type" void (*)(int) peut apparaître dans d'autres
expressions, y a-t-il une explication à ça ?

--
"Yo!"
Martin Heidegger

7 réponses

Avatar
Jean-Marc Bourguet
Yoxoman writes:

Bonjour à tous.

On déclare un pointeur de fontion vers une fonction void f(int) comme ça
:

void (*p)(int) = f;

et pas comme ça :

void (*)(int) p = f;

Etant donné que le "type" void (*)(int) peut apparaître dans d'autres
expressions, y a-t-il une explication à ça ?


Le principe des declarations en C et donc en C++ c'est qu'une
declaration a la meme forme que l'utilisation. On utilise p
comme ceci

(*p)(5)

donc on le declare comme ca

void (*p)(int)

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
James Kanze
Jean-Marc Bourguet wrote:
Yoxoman writes:


On déclare un pointeur de fontion vers une fonction void
f(int) comme ça :



void (*p)(int) = f;



et pas comme ça :



void (*)(int) p = f;



Etant donné que le "type" void (*)(int) peut apparaître dans
d'autres expressions, y a-t-il une explication à ça ?



Le principe des declarations en C et donc en C++ c'est qu'une
declaration a la meme forme que l'utilisation.


C'était, non c'est. Ça a cessé d'être le cas dès l'introduction
de typedef.

C'est bien la motivation historique (et c'est bien l'explication
ici), mais c'est vraiment historique.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
meow
void (*)(int) p = f;
Cette ecriture ressemble à un cast... ça peut se faire, des casts de

pointeurs de fonction ?

Avatar
Fabien LE LEZ
On 21 Nov 2005 07:51:24 -0800, "meow" :

void (*)(int) p = f;


Cette ecriture ressemble à un cast...


Non.

ça peut se faire, des casts de pointeurs de fonction ?


Oui. Mais je ne connais qu'un cas où c'est utile : faire passer un
pointeur de fonction par un mécanisme, généralement propre à une
plate-forme, qui fait perdre le typage. Exemple : les "messages" de
Win32, qui n'acceptent comme arguments que des "unsigned long".
En pratique, c'est hautement non portable.


Avatar
kanze
Fabien LE LEZ wrote:
On 21 Nov 2005 07:51:24 -0800, "meow" :

void (*)(int) p = f;


Cette ecriture ressemble à un cast...


Non.

ça peut se faire, des casts de pointeurs de fonction ?


Oui. Mais je ne connais qu'un cas où c'est utile : faire
passer un pointeur de fonction par un mécanisme, généralement
propre à une plate-forme, qui fait perdre le typage. Exemple :
les "messages" de Win32, qui n'acceptent comme arguments que
des "unsigned long". En pratique, c'est hautement non
portable.


Il y a au moins deux cas où il peut servir de façon portable :

-- Il n'y a pas d'équivalent à void* pour les pointeurs à des
fonctions, mais il arrive qu'on se sert de void (*)() pour
ça. Alors, il faut une conversion explicite à l'affectation
et à la rélecture. Si la deuxième conversion est vers le
type initial, le code est conform, et on peut se servir du
pointeur. (Les cas où on voudrait faire ceci sont rarissme,
mais la norme le garantit.)

-- On se sert du syntaxe de cast pour spécifier explicitement
la résolution du surcharge quand on prend l'adresse d'une
fonction surchargée, et que la contexte ne permet pas au
compilateur de le résoudre lui-même. Imaginons que j'ai
quelque chose comme :

extern bool isOk( int ) ;
extern bool isOk( double ) ;
extern std::vector< int > a ;

// ...
if ( std::find_if( a.begin(), a.end(), &isOk ) ) // ...

Le compilateur a un problème ici pour la résolution du
surcharge de isOk, parce qu'il s'agit de l'affecter à un
paramètre du template. Il faut donc que nous le spécifions
explicitement :

if ( std::find_if( a.begin(), b.begin(),
static_cast< bool (*)(int) >( &isOk ) ) )
// ...

(C'est encore une raison pour préférer les objets
fonctionnels:-).)

--
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



Avatar
Fabien LE LEZ
On 21 Nov 2005 23:40:35 -0800, "kanze" :

-- On se sert du syntaxe de cast pour spécifier explicitement
la résolution du surcharge


Mais ce n'est pas réellement un cast (i.e. le type reste le même).

Avatar
kanze
Fabien LE LEZ wrote:
On 21 Nov 2005 23:40:35 -0800, "kanze" :

-- On se sert du syntaxe de cast pour spécifier explicitement
la résolution du surcharge


Mais ce n'est pas réellement un cast (i.e. le type reste le
même).


Ce n'est pas une conversion de type. Est-ce un cast ? Je ne sais
pas. Je ne trouve pas le mot « cast » dans mes dictionnaires,
pour en savoir la signification exacte:-). (Note que même les
dictionnaires anglais n'aident pas. Le mot a une signification
très spéciale uniquement dans le contexte C/C++.)

A priori, je dirais que le mot réfère à un certain nombre de
syntaxes (originalement un), qui servent habituellement à la
conversion explicite des types. Si je veux parler de la
conversion, et non de la syntaxe, je dirais conversion, et non
cast. Mais ben, je reconnais que c'est un peu arbitraire, et
qu'il n'y a pas d'arbitre pour trancher. C'est pour ça que j'ai
bien dit qu'« on se sert du syntaxe de cast » ; je ne voulais
pas m'engager sur la nomenclature, mais je trouvais qu'il valait
la peine de citer le cas quand même.

--
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