OVH Cloud OVH Cloud

Argument de fonction par default

22 réponses
Avatar
Tanski Mikael
Hello,

Alors voila j'ai cette définition de fonction :
BOOL Create(
UINT nSocketPort = 0,
int nSocketType = SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT |
FD_CLOSE,
LPCTSTR lpszSocketAddress = NULL
);

Vous remarquez qu'il y a des arguments par default, notamment lEvent qui
est bien long (en terme de caractéres, pas de type).
Alors voila j'ai besoin de redéfinire tous les arguments sauf lEvent.

Y a til un moyen de faire cela en c++? Pour rendre plus clair la chose,
je voudrais pouvoir appeler la fonction un peux comme sa :

Create(80,SOCK_STREAM,,"127.0.0.1");

Je vous demande cela juste pour eviter en faite de recopier la longue
série FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE...

Bon d'accord c'est pas trés clair, mais si quelqu'un voit, merci à lui...

10 réponses

1 2 3
Avatar
Pierre Maurette
"drkm" <fr.comp.lang.c++@fgeorges.org> a écrit

int const unNomQuiVaBien = FD_READ | FD_... ;

Où est le problème ?
Pourquoi "int" ?

Pourquoi pas "unsigned int" ?
Pourquoi pas
"Type_de_la_mort_typedefé_par_microsoft_supportant_le_OR_bitabit" ?

En fait, en réfléchissant à la lecture de votre message, je
m'apperçois qu'il faut aller plus loin : quelle que soit la façon
dont sont définis les FD_xxx, c'est un #define qu'il FAUT utiliser :


?

le but est de pouvoir typer FD_ALL en lieu et place de FD_READ |
... | FD_CLOSE. Ainsi, après le travail du prétraitement, je ne
modifie en rien le fonctionnement, le type,


?

je n'ai pas à connaitre le contenu du winsock.h et je suis résistant
à sa modification dans de futures versions de l'API.


?
Le #define est une instruction de préprocessing.

La norme nuance, mais EN GROS, il y a une phase pendant laquelle le source
est préparé à la compilation : nettoyage des espaces inutiles, des
commentaires, traitement des fins de lignes par , traduction des trigraphs
(sans intérêt immédiat, pas de ?), prise en compte du jeu de caractères, que
sais-je encore. Elimination du code non compilé (#if... #endif). Inclusions
des fichier par les #include. Et surtout, développement des macros. Donc, le
vrai compilateur, ou la vraie couche de compilation, reçoit un listing
"épuré". Il est possible d'obtenir ce listing. Ça reste du code source C++,
en ce sens qu'il est possible de le compiler, voire de l'éditer.
Donc, si vous faites :
#define FD_ALL FD_READ | ... | FD_CLOSE
...
Create(80,SOCK_STREAM,FD_ALL,"127.0.0.1");

Le vrai compilateur reçoit :
Create(80,SOCK_STREAM,FD_READ | ... | FD_CLOSE,"127.0.0.1");
ou plus exactement il reçoit exactement ce qu'il aurait reçu sui j'avais
tapé cette dernière ligne, puisque les FD_READ etc. vont eux aussi être
développés.
Par exemple, et seulement par exemple :
Create(80,JeanSaisRien,0x01| ... | 0x10,"127.0.0.1");
(JeanSaisRien, parce que je ne sais pas ce qu'est SOCK_STREAM, et je m'en
tape)

Maintenant, imaginons que dans une future version, le fichier .h soit
modifié :
const unsigned long long FD_READ = 0x0000000000000001;
(j'ai dit future).
Si la compatibilité est assurée, c.à d. si :
Create(80,SOCK_STREAM,FD_READ | ... | FD_CLOSE,"127.0.0.1");
compile toujours, alors le #define FD_ALL etc. fonctionnera toujours
également.

Il n'est pas besoin de future version pour justifier le #define, puisque
sans même vérifier si les FD_READ etc. sont typés, et quel est le type, vous
savez que le #define en conservera "l'essence".

Comme d'autres éléments du langage, les macros ont mauvaise presse. Il y a
peut-être eu des abus, par exemple celui de définir une constante par une
macro. Quelques pièges à cons également, dans les macros à paramètres. Mais
la notion n'est pas deprecated, et irremplaçable dans son acception de
"raccourci clavier" par exemple.

Pierre


Avatar
Pierre Maurette
"Fabien LE LEZ" a
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

En fait, en réfléchissant à la lecture de votre message, je m'apperçois
qu'il faut aller plus loin : quelle que soit la façon dont sont définis
les


FD_xxx, c'est un #define qu'il FAUT utiliser : le but est de pouvoir
typer


FD_ALL en lieu et place de FD_READ | ... | FD_CLOSE. Ainsi, après le
travail


du prétraitement, je ne modifie en rien le fonctionnement, le type, je
n'ai


pas à connaitre le contenu du winsock.h et je suis résistant à sa
modification dans de futures versions de l'API.


... sauf la version qui #définira un FD_ALL différent du tien.

On sait par contre que l'argument lEvent est un long (et le restera
vraisemblablement), on peut donc créer une constante "locale" de type
"long", égale à FD_READ | ... | FD_CLOSE.


Là, on vire un peu "100 minutes pour convaincre", non ?
Ce qui m'intéresse, c'est que tout ça permet de réfléchir aux domaines
d'application des macros et des constantes typées. Hors, une macro sur une
constante typée se développe en une constante typée :
const double PasBoNom = 3.14159;
#define MonPi_Meuh PasBoNom


Pierre


Avatar
Fabien LE LEZ
On Wed, 31 Dec 2003 09:05:29 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

une macro sur

une


Je ne suis pas d'accord avec ce mot.

constante typée se développe en une constante typée :


namespace ns1
{
const double PasBoNom = 3.14159;
#define MonPi_Meuh PasBoNom
};


namespace ns2
{

void MonPi_Meuh (int);

struct C
{
void PasBoNom (int i) { MonPi_Meuh (i); }
};

}


Maintenant, tu fais ce que tu veux ; j'espère juste ne jamais tomber
sur un code de ton cru.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2

Avatar
Fabien LE LEZ
On Wed, 31 Dec 2003 08:46:26 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

int const unNomQuiVaBien = FD_READ | FD_... ;

Où est le problème ?
Pourquoi "int" ?



C'est effectivement une erreur.
Le type réclamé par la fonction est long, donc la variable
unNomQuiVaBien devrait être de ce type.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2


Avatar
Fabien LE LEZ
On Wed, 31 Dec 2003 08:46:26 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

les macros ont mauvaise presse.


Tout simplement parce qu'elles sont très difficiles à utiliser.
Une macro n'a pas de limitation de portée, il faut donc s'assurer
soi-même qu'un identifiant ne portera pas le même nom. Une méthode
commune pour cela (et que j'applique systématiquement) est d'indiquer,
dans le nom de la macro, qu'il s'agit d'une macro :

#define MACRO_Machin_truc ...

On peut également simuler une portée, pour les macros à usage local :

void f()
{
#define MACRO_exec_log(x) x; cerr << #x << endl;
MACRO_exec_log (g(1))
MACRO_exec_log (h(3))
#undef MACRO_exec_log
}

Et bien sûr, comme pour toutes les notions compliquées et dangereuses,
on ne s'en sert qu'en dernier recours.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2

Avatar
Pierre Maurette
"Fabien LE LEZ" a écrit
[...]
Maintenant, tu fais ce que tu veux ; j'espère juste ne jamais tomber
sur un code de ton cru.
Sincèrement, et c'est le jour et l'heure qui veut ça, c'est ce que je te

souhaite pour 2004 ;-)
Meilleurs voeux,
Pierre
PS: je n'ai rien rouvé dans le registre du contrepet avec :
"j'espère juste ne jamais tomber sur un code de ton cru"
Pourtant, je preessens quelque chose ....

Avatar
Pierre Maurette
"Fabien LE LEZ" a écrit ...
On Wed, 31 Dec 2003 08:46:26 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

les macros ont mauvaise presse.


Tout simplement parce qu'elles sont très difficiles à utiliser.
Il faut vivre dangereusement ...


Une macro n'a pas de limitation de portée, il faut donc s'assurer
soi-même qu'un identifiant ne portera pas le même nom. Une méthode
commune pour cela (et que j'applique systématiquement) est d'indiquer,
dans le nom de la macro, qu'il s'agit d'une macro :

#define MACRO_Machin_truc ...
Je fais pareil :

#define MACRO_AU_VIN_BLANC
#define MACRO_EN_PAPILLOTTE
#define MACRO_A_LA_MOUTARDE
(je te fais grâce de la parenthèse joviale).

On peut également simuler une portée, pour les macros à usage local :

void f()
{
#define MACRO_exec_log(x) x; cerr << #x << endl;
MACRO_exec_log (g(1))
MACRO_exec_log (h(3))
#undef MACRO_exec_log
}
Le #define / #undef, c'est une des bases de travail avec un préprocessseur.

Quel que soit le langage.

Bon, contrairement aux apparences, je n'ai pas commencé les agapes, j'y vais
de ce pas.
Encore tous mes voeux,
Pierre


Avatar
Fabien LE LEZ
On Wed, 31 Dec 2003 21:52:52 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

Tout simplement parce qu'elles sont très difficiles à utiliser.


Il faut vivre dangereusement ...


Non.
Un code bien pensé doit fonctionner parfaitement presque du premier
coup, sans qu'on ait à passer des heures à essayer de comprendre d'où
vient tel ou tel bug. C'est pourquoi une technique potentiellement
dangereuse doit n'être utilisée qu'en dernier recours, voire jamais.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2


Avatar
Fabien LE LEZ
On Wed, 31 Dec 2003 21:37:35 +0100, "Pierre Maurette"
<mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote:

PS: je n'ai rien rouvé dans le registre du contrepet avec :
"j'espère juste ne jamais tomber sur un code de ton cru"
Pourtant, je preessens quelque chose ....


Maintenant que tu le dis, c'est effectivement possible. Mais je suis
très mauvais dans le registre du contrepet.

--
;-)

http://www.gotw.ca/gotw/063.htm
http://www.gotw.ca/gotw/067.htm#2

Avatar
ricky
hello

Un code bien pensé doit fonctionner parfaitement presque du premier
coup, sans qu'on ait à passer des heures à essayer de comprendre d'où
vient tel ou tel bug.


au pays de candy surement :-)
mais dans les fait, son poids en cacahouetes a celui qui y arrive a tous
les coups, meme si le code est bien pense :-)

C'est pourquoi une technique potentiellement
dangereuse doit n'être utilisée qu'en dernier recours, voire jamais.


a part le "jamais", tout a fait d'accord
mais bon, si c 'est un dernier recours et que le reste est epuise, quand
meme, un peu de bonte d'ame :-)

@+
ricky : bonnes resolutions en 2004, plus de troll :-) enfin presque ...

1 2 3