C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Quel opérateur de cast ?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
meow
Guest





PostPosted: Thu Jul 13, 2006 8:37 pm    Post subject: Quel opérateur de cast ? Reply with quote



Hello,

Plutot que de relire pour la dixième fois le 30 chapitres et
tutoriaux sur les cast, auxquels je n'ai toujours rien panné, j'ai
décidé de changer de technique : je pose la question sur un cas
concret et j'affinerai ma connaissance au fur et à mesure. Dans
l'extrait de code :

Volumetric* create(Kind k){
Volumetric* v;
switch (k) {
case RAW:
v =new RawVolumetric;break;
default:
v =NULL;break;
}
return v;
}

il y a un v=NULL qui ne me semble pas très joli. Il faudrait tout du
moins que je le caste en Volumetric*, non ? Et si oui, quel operateur
dois-je utiliser ?

--Ben
Back to top
Michel Decima
Guest





PostPosted: Thu Jul 13, 2006 8:52 pm    Post subject: Re: Quel opérateur de cast ? Reply with quote



meow a écrit :
Quote:
Hello,

Plutot que de relire pour la dixième fois le 30 chapitres et
tutoriaux sur les cast, auxquels je n'ai toujours rien panné, j'ai
décidé de changer de technique : je pose la question sur un cas
concret et j'affinerai ma connaissance au fur et à mesure. Dans
l'extrait de code :

Volumetric* create(Kind k){
Volumetric* v;
switch (k) {
case RAW:
v =new RawVolumetric;break;
default:
v =NULL;break;
}
return v;
}

il y a un v=NULL qui ne me semble pas très joli.

Tu peux remplacer par v=0, c'est equivalent.

Quote:
Il faudrait tout du moins que je le caste en Volumetric*, non ?

non.

> Et si oui, quel operateur dois-je utiliser ?
Back to top
meow
Guest





PostPosted: Thu Jul 13, 2006 9:02 pm    Post subject: Re: Quel opérateur de cast ? Reply with quote



Quote:
Tu peux remplacer par v=0, c'est equivalent.

Euh... C'est pas dangereux ? Je veux dire, jusqu'à présent, tous les
NULL que j'ai vu valaient effectivement 0, mais bon, j'imagines que si
on a inventé NULL c'est justement pour s'abstraire de la valeur, non ?

Quote:
Il faudrait tout du moins que je le caste en Volumetric*, non ?
non.

O_o
Mon compilo dit la meme chose que toi, mais je ne comprends pas bien.
Pour moi, NULL est (void*) par défaut... Ou en tout cas, tout sauf
typé.
Back to top
Sylvain Togni
Guest





PostPosted: Thu Jul 13, 2006 9:19 pm    Post subject: Re: Quel opérateur de cast ? Reply with quote

meow a écrit :
Quote:
Tu peux remplacer par v=0, c'est equivalent.

Euh... C'est pas dangereux ? Je veux dire, jusqu'à présent, tous les
NULL que j'ai vu valaient effectivement 0, mais bon, j'imagines que si
on a inventé NULL c'est justement pour s'abstraire de la valeur, non ?

Il faudrait tout du moins que je le caste en Volumetric*, non ?
non.

O_o
Mon compilo dit la meme chose que toi, mais je ne comprends pas bien.
Pour moi, NULL est (void*) par défaut... Ou en tout cas, tout sauf
typé.

En C++, NULL est de type entier, car il n'y a pas de conversion
void* -> T*, contrairement au C.

Il est le plus souvent défini ainsi:

#define NULL 0

Ce qui fait qu'utiliser NULL ou 0 est une affaire de goût.

--
Sylvain Togni
Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Jul 13, 2006 10:26 pm    Post subject: Re: Quel opérateur de cast ? Reply with quote

On 13 Jul 2006 08:37:41 -0700, "meow" <schwarz.ben (AT) gmail (DOT) com>:

Quote:
Volumetric* create(Kind k){
Volumetric* v;

Ça ne répond pas directement à ta question, mais j'aurais tendance à
mettre le 0/NULL ici :


Volumetric* create(Kind k)
{
Volumetric* v= 0;


D'une manière générale, je n'aime pas avoir une variable non
initialisée.

En prime, ici, on a une valeur par défaut toute trouvée (0/NULL),
qu'on ne modifie que si on a effectivement une nouvelle valeur.

La fonction devient alors :

Volumetric* create (Kind k)
{
Volumetric* v= 0;

switch (k)
{
case RAW: v= new RawVolumetric;break;
}
return v;
}

Note qu'à tout moment, v est un pointeur valide, sur lequel on peut
appeler delete sans problème.




J'aurais tendance à écrire

Volumetric* create (Kind k)
{
switch (k)
{
case RAW: return new RawVolumetric;
}
return 0;
}

mais certains n'aiment pas les fonctions avec plusieurs "return" ;
j'avoue ne pas trop savoir pourquoi.
Back to top
Arnaud Meurgues
Guest





PostPosted: Thu Jul 13, 2006 11:30 pm    Post subject: Re: Quel opérateur de cast ? Reply with quote

meow wrote:

Quote:
Il faudrait tout du moins que je le caste en Volumetric*, non ?
non.
O_o
Mon compilo dit la meme chose que toi, mais je ne comprends pas bien.
Pour moi, NULL est (void*) par défaut...

Ce que dit la norme qui vaut sans doute mieux qu'un long discours :

4.10/1
A null pointer constant is an integral constant expression (5.19) rvalue
of integer type that evaluates to zero. A null pointer constant can be
converted to a pointer type; the result is the null pointer value of
that type and is distinguishable from every other value of pointer to
object or pointer to function type. Two null pointer values of the same
type shall compare equal. The conversion of a null pointer constant to a
pointer to cvqualified type is a single conversion, and not the sequence
of a pointer conversion followed by a qualification conversion (4.4).

4.11/1
A null pointer constant (4.10) can be converted to a pointer to member
type; the result is the null member pointer value of that type and is
distinguishable from any pointer to member not created from a null
pointer constant. Two null member pointer values of the same type shall
compare equal. The conversion of a null pointer constant to a pointer to
member of cvqualified type is a single conversion, and not the sequence
of a pointer to member conversion followed by a qualification conversion
(4.4)

18.1/4
The macro NULL is an implementation-defined C++ null pointer constant in
this International Standard (4.10).

--
Arnaud
Back to top
Loïc Joly
Guest





PostPosted: Fri Jul 14, 2006 12:32 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Fabien LE LEZ a écrit :
Quote:

mais certains n'aiment pas les fonctions avec plusieurs "return" ;
j'avoue ne pas trop savoir pourquoi.


Dans un langage qui n'aiderait pas à nettoyer des données en sortie de
code (comme peuvent le faire les destructeurs du C++, les using(){} du
C#, les try/finally de Java), je n'aimerai pas non plus le code à
plusieurs return. Ni les exceptions (qui sont un cas similaire).

Je pesne que les tenants du SESE ont fait leurs premières armes avec des
langages comme C, où ça a un intérêt certain.

--
Loïc
Back to top
James Kanze
Guest





PostPosted: Fri Jul 14, 2006 1:47 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

meow wrote:

Quote:
Plutot que de relire pour la dixième fois le 30 chapitres et
tutoriaux sur les cast, auxquels je n'ai toujours rien panné, j'ai
décidé de changer de technique : je pose la question sur un cas
concret et j'affinerai ma connaissance au fur et à mesure. Dans
l'extrait de code :

Volumetric* create(Kind k){
Volumetric* v;
switch (k) {
case RAW:
v =new RawVolumetric;break;
default:
v =NULL;break;
}
return v;
}

il y a un v=NULL qui ne me semble pas très joli.

Pourquoi ? Il faut bien lui affecter le pointeur null, non ?

Quote:
Il faudrait tout du moins que je le caste en Volumetric*, non ?

Non. Mais la raison est un peu perverse. Grosso modo :

-- En C++, il y a un concepte d'une constante de pointeur null (un
« null pointer constant ». Malgré son nom, il n'est pas un
pointeur, mais une « expression constante entière dont la valeur
est 0 ». Il peut être donc « 0 », « 1 - 1 » ou n'importe quelle
autre expression qui a un type entier, et qui s'évalue à 0.

Ce qui caractèrise cette expression, c'est qu'elle se convertit
implicitement en n'importe quel type de pointeur, et que le résultat
de cette conversion, c'est un pointeur null. Note bien que pour que
ça a lieu, il faut que toutes les exigences soient remplies : que
l'expression soit conforme à ce que le langage considère une
expression entière constante, et qu'elle s'évalue à 0. (Il y a eu
une discussion récemment dans le groupe anglophone, du fait que
« (0, 0) » n'est pas, malgré les apparences, une expression
constante entière.)

Note bien aussi qu'il n'y a aucune exigeance qu'un pointeur null ait
tous les bits à zéro. Il s'agit ici d'une conversion, et c'est le
problème du compilateur à faire en sorte que ça marche correctement.
(Note bien aussi que si tu fais un « reinterpret_cast » d'une
variable de type int, dont la valeur est 0, ce n'est pas garantie
que tu ais le même résultat que si tu as une expression constante
qui vaut 0.)

-- La macro NULL est guarantie à répresenter une constante de pointeur
null. Souvent, c'est simplement « 0 », mais sur un bon
compilateur, ça serait quelque chose du genre __nullptr, de façon à
générer un avertissement si tu t'en sers comme entier. Selon la
norme :
int i = NULL ;
est légal, mais je connais personne qui le considère bien.

-- La situation est, comme j'ai dit, un peu perverse. Quand on connaît
les origines de C, on comprend comment on y est arrivé, mais dans un
langage fortement typé comme le C++, c'est vraiment une aberration.
Aussi y'a-t-il une proposition pour créer un véritable nullptr, qui
a, je crois, de fortes chances de faire partie de la prochaine
version de C++.

Quote:
Et si oui, quel operateur dois-je utiliser ?

Ici, je dirais aucun.

Ici. Parce que le type de la constante de pointeur null n'est pas ce
qu'on pourrait s'attendre (et parce que de toute façon, il ne pourrait
pas avoir le type de tous les pointeurs à la fois), il y a des contextes
où il faut une conversion explicite. Celui qui me vient tout de suite à
l'esprit, c'est quand on le passe à une fonction « varargs », c-à-d
quand il correspond à un paramètre désigné par « ... ». Dans ce
cas-là, le compilateur ne connaît pas le type voulu, et est obligé à
croire au type donné, c-à-d int (ou un autre type entier). Il faut donc
explicitement préciser le type voulu. Dans ces cas-là, c'est le
static_cast qui convient.

--
James Kanze kanze.james (AT) neuf (DOT) 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
Back to top
James Kanze
Guest





PostPosted: Fri Jul 14, 2006 1:56 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Fabien LE LEZ wrote:
Quote:
On 13 Jul 2006 08:37:41 -0700, "meow" <schwarz.ben (AT) gmail (DOT) com>:

Volumetric* create(Kind k){
Volumetric* v;

Ça ne répond pas directement à ta question, mais j'aurais tendance à
mettre le 0/NULL ici :

Volumetric* create(Kind k)
{
Volumetric* v= 0;

D'une manière générale, je n'aime pas avoir une variable non
initialisée.

En prime, ici, on a une valeur par défaut toute trouvée (0/NULL),
qu'on ne modifie que si on a effectivement une nouvelle valeur.

Tout à fait d'accord.

Quote:
La fonction devient alors :

Volumetric* create (Kind k)
{
Volumetric* v= 0;

switch (k)
{
case RAW: v= new RawVolumetric;break;
}
return v;
}

Note qu'à tout moment, v est un pointeur valide, sur lequel on peut
appeler delete sans problème.

Ici, ce n'est pas un problème, parce qu'il s'agit d'une variable locale,
mais dans le cas général, c'est réconfortant à savoir que même si le new
lève une exception, le pointeur a une valeur légitime.

Quote:
J'aurais tendance à écrire

Volumetric* create (Kind k)
{
switch (k)
{
case RAW: return new RawVolumetric;
}
return 0;
}

mais certains n'aiment pas les fonctions avec plusieurs "return" ;
j'avoue ne pas trop savoir pourquoi.

Parce qu'on aime pouvoir raisonner de façon rigueureuse sur la
correction du code.

Ce qui ne veut pas dire qu'on n'admet pas d'exception. Dans un cas comme
ceci, j'admets volentiers quelque chose du genre :

Volumetric*
create( Kind k )
{
switch ( k )
{
case RAW :
return new RawVolumetric ;

// ...

default :
return NULL ;
}
}

Mais je le limite aux cas où :

-- la seule instruction dans la fonction est le switch,
-- tous les cas du switch contient une seule instruction, qui est le
return, et
-- il y a un default.

Aussi, dans l'ensemble, ce n'est pas si utile que ça, parce que les
switch sont assez rare. Bien plus souvent, j'aurais quelque chose du
genre :

Volumetric*
create( Kind k )
{
Map::const_iterator iter = map.find( k ) ;
return iter == map.end()
? NULL
: iter->second->create() ;
}

L'avantage, évidemment, c'est que je peux ajouter des types sans toucher
au code existant.

--
James Kanze kanze.james (AT) neuf (DOT) 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
Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Jul 14, 2006 3:20 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

On Thu, 13 Jul 2006 22:47:38 +0200, James Kanze <kanze.james (AT) neuf (DOT) fr>:

Quote:
(Il y a eu
une discussion récemment dans le groupe anglophone, du fait que
« (0, 0) » n'est pas, malgré les apparences, une expression
constante entière.)

Tiens ? Qu'est-ce donc, alors ?

Quote:
(Note bien aussi que si tu fais un « reinterpret_cast » d'une
variable de type int, dont la valeur est 0, ce n'est pas garantie
que tu ais le même résultat que si tu as une expression constante
qui vaut 0.)

Si je ne m'abuse, on peut généraliser : si tu fais un
"reinterpret_cast<T*>(i)", où "i" est un nombre, tu n'as absolument
aucune garantie...
Back to top
Fabien LE LEZ
Guest





PostPosted: Fri Jul 14, 2006 3:36 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

On Thu, 13 Jul 2006 22:56:53 +0200, James Kanze <kanze.james (AT) neuf (DOT) fr>:

Quote:
mais certains n'aiment pas les fonctions avec plusieurs "return" ;
j'avoue ne pas trop savoir pourquoi.

Parce qu'on aime pouvoir raisonner de façon rigueureuse sur la
correction du code.

Ce qui ne veut pas dire qu'on n'admet pas d'exception.

Justement, parlons-en, des exceptions... (Au sens C++, pour le coup.)

Le mécanisme des exceptions fait que de toutes façons, dans la plupart
des fonctions non triviales, il y a une possibilité pour qu'on sorte
de la fonction par un autre endroit que le "return".
Par conséquent, la durée de vie des objets locaux, et la validité des
objets "externes", ne doit pas se baser sur le principe SESE.

D'autre part, il me semble que le compilateur se charge de s'assurer
que quelque soit le cheminement dans la fonction, une valeur de retour
est bien renvoyée.

Du coup, je ne vois pas bien ce que se forcer à mettre un seul
"return", avec toutes les circonvolutions que ça amène parfois,
apporte réellement.

Au fait, question subsidiaire : j'ai toujours entendu parler de
"single entry, single exit", et j'avoue que je ne saisis pas bien le
"single entry" : on peut entrer dans une fonction par un autre endroit
que le début ? Ou l'expression est comme ça par pur amour de la
symétrie ?
Back to top
Loïc Joly
Guest





PostPosted: Fri Jul 14, 2006 4:18 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Fabien LE LEZ a écrit :

Quote:
Au fait, question subsidiaire : j'ai toujours entendu parler de
"single entry, single exit", et j'avoue que je ne saisis pas bien le
"single entry" : on peut entrer dans une fonction par un autre endroit
que le début ?

Dans certains langages, on peut. En vieux basic, avec Gosub, on peut
entrer où on veut dans une "fonction".

--
Loïc
Back to top
Sylvain
Guest





PostPosted: Fri Jul 14, 2006 4:23 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Loïc Joly wrote on 14/07/2006 01:18:
Quote:

Dans certains langages, on peut. En vieux basic, avec Gosub, on peut
entrer où on veut dans une "fonction".

en fortran courant également et surement en C à coup de 'setjmp'.

Sylvain.
Back to top
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 14, 2006 9:11 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Fabien LE LEZ <gramster (AT) gramster (DOT) com> writes:

Quote:
Au fait, question subsidiaire : j'ai toujours entendu parler de
"single entry, single exit", et j'avoue que je ne saisis pas bien le
"single entry" : on peut entrer dans une fonction par un autre endroit
que le début ?

C'est naturellement possible en assembleur. Ce l'a été dans
certains langages (FORTRAN, BLISS, peut-être BCPL).

Mais l'expression SESE concerne n'importe quel bloc
structurel. Et avoir plusieurs entrées pour en bloc en C++,
c'est possible en jouant avec goto (ou switch, voir duff
device).

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
Jean-Marc Bourguet
Guest





PostPosted: Fri Jul 14, 2006 9:11 am    Post subject: Re: Quel opérateur de cast ? Reply with quote

Fabien LE LEZ <gramster (AT) gramster (DOT) com> writes:

Quote:
On Thu, 13 Jul 2006 22:47:38 +0200, James Kanze <kanze.james (AT) neuf (DOT) fr>:

(Il y a eu
une discussion récemment dans le groupe anglophone, du fait que
« (0, 0) » n'est pas, malgré les apparences, une expression
constante entière.)

Tiens ? Qu'est-ce donc, alors ?

C'est une expression entière non constante. Tu ne peux pas
faire quelque chose comme:

int i[(0, 5)];

Quote:
(Note bien aussi que si tu fais un « reinterpret_cast
» d'une variable de type int, dont la valeur est 0,
ce n'est pas garantie que tu ais le même résultat que
si tu as une expression constante qui vaut 0.)

Si je ne m'abuse, on peut généraliser : si tu fais un
"reinterpret_cast<T*>(i)", où "i" est un nombre, tu n'as
absolument aucune garantie...

La valeur 0 est la seule pour laquelle il soit sensé de
faire une différence entre expression constante et non
constante lors de la détermination du résultat.

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.