Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

cast de pointeur passé à une fonction

20 réponses
Avatar
Pierre Maurette
Bonjour,

foo() est pour l'exemple une fonction dont je ne connais pas
l'implémentation. Le paramètre est en sortie, mais il pourrait aussi
bien être en entrée - sortie.

void foo(short* param);
int i;
short temp;
/* ... */
foo(&i); // cas 1
foo((short*)&i); // cas 2
foo(&(short)i); // cas 3
//temp = i;
foo(&temp); // cas 4
i = temp;

Je précise que j'utilise systématiquement le temporaire explicite (cas
4) et que je ne vois pas de raison de changer.

- Le cas 1 doit être au moins à l'origine d'un gros warning.

- Le cas 2 n'est pas portable. Il ne pourrait être utilisable que dans
un environnement connu, en maîtrisant l'implémentation de foo() et avec
le risque de se vautrer lors de la réutilisation de cette fonction. Et
dans ces conditions, pourquoi utiliser au départ un short* et non un
void*, hein ?

- Donc, les cas 1 et 2 sont des horreurs mais je vois - ou crois voir -
à peu près le déroulement des opérations. C'est ce qui se passe dans le
cas 3 qui me pose problème. La réponse doit être dans la norme mais je
n'ai rien trouvé. Dans une vision "petit boutiste" de la chose, on
imagine d'abord que le comportement est le même que pour les cas 1 et
2, c'est à dire le passage de l'adresse de i. Disons (short*)(void*)&i.
Mais l'évocation du "gros bout" me plonge dans un abîme de perplexité.

Donc, en bref, qu'est-ce que &(short)i ?

Merci pour vos lumières, et bonne journée...

--
Pierre Maurette

10 réponses

1 2
Avatar
Pierre Maurette
Bonjour,

foo() est pour l'exemple une fonction dont je ne connais pas
l'implémentation. Le paramètre est en sortie, mais il pourrait aussi bien
être en entrée - sortie.

void foo(short* param);
int i;
short temp;
/* ... */
foo(&i); // cas 1
foo((short*)&i); // cas 2
foo(&(short)i); // cas 3
//temp = i;
foo(&temp); // cas 4
i = temp;

Je précise que j'utilise systématiquement le temporaire explicite (cas 4) et
que je ne vois pas de raison de changer.

- Le cas 1 doit être au moins à l'origine d'un gros warning.

- Le cas 2 n'est pas portable. Il ne pourrait être utilisable que dans un
environnement connu, en maîtrisant l'implémentation de foo() et avec le
risque de se vautrer lors de la réutilisation de cette fonction. Et dans ces
conditions, pourquoi utiliser au départ un short* et non un void*, hein ?

- Donc, les cas 1 et 2 sont des horreurs mais je vois - ou crois voir - à peu
près le déroulement des opérations. C'est ce qui se passe dans le cas 3 qui
me pose problème. La réponse doit être dans la norme mais je n'ai rien
trouvé. Dans une vision "petit boutiste" de la chose, on imagine d'abord que
le comportement est le même que pour les cas 1 et 2, c'est à dire le passage
de l'adresse de i. Disons (short*)(void*)&i. Mais l'évocation du "gros bout"
me plonge dans un abîme de perplexité.

Donc, en bref, qu'est-ce que &(short)i ?

Merci pour vos lumières, et bonne journée...


Oooooops ! Je m'étais laissé gruger par mon compilateur, iCC 10.0.
Comme je l'avais lu dans la norme et comme le voulait la logique,
&(short)i n'a aucun sens, puisque le cast ne donne pas une lvalue, et
il est impossible de prendre l'adresse de (short)i. C'est effectivement
refusé par gcc.
iCC le prend sans warning, et renvoie l'adresse de i tout simplement.
Même si iCC ne compile que pour son seul boutisme, c'est quand même
bien étrange...

--
Pierre Maurette

Avatar
espie
In article ,
Pierre Maurette wrote:
Oooooops ! Je m'étais laissé gruger par mon compilateur, iCC 10.0.
Comme je l'avais lu dans la norme et comme le voulait la logique,
&(short)i n'a aucun sens, puisque le cast ne donne pas une lvalue, et
il est impossible de prendre l'adresse de (short)i. C'est effectivement
refusé par gcc.
iCC le prend sans warning, et renvoie l'adresse de i tout simplement.
Même si iCC ne compile que pour son seul boutisme, c'est quand même
bien étrange...


iCC, c'est bien le compilo Intel ? Quand on voit les bugs qu'ils ont
laisse passer dans leurs derniers processeurs, on s'etonne moins du
comportement du compilo...

Avatar
Stéphane Zuckerman
On Tue, 17 Jul 2007, Marc Espie wrote:

iCC, c'est bien le compilo Intel ? Quand on voit les bugs qu'ils ont
laisse passer dans leurs derniers processeurs, on s'etonne moins du
comportement du compilo...


Il faut relativiser. Lorsqu'on compile avec gcc, il faut nécessairement
faire un -Wall -W -W...
Avec icc, on a l'équivalent d'un -Wall tout de suite. Lorsqu'on active le
-Wall d'icc, on a surtout droit à des "remark #1445". Lorsqu'on n'a plus
de "remark", généralement, le code est réellement portable.

Maintenant oui, ICC a des bugs, mais bon, faut-il rappeler que GCC
(surtout dans sa version 4) aussi ?


--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
espie
In article ,
Stéphane Zuckerman wrote:
On Tue, 17 Jul 2007, Marc Espie wrote:

iCC, c'est bien le compilo Intel ? Quand on voit les bugs qu'ils ont
laisse passer dans leurs derniers processeurs, on s'etonne moins du
comportement du compilo...


Il faut relativiser. Lorsqu'on compile avec gcc, il faut nécessairement
faire un -Wall -W -W...
Avec icc, on a l'équivalent d'un -Wall tout de suite. Lorsqu'on active le
-Wall d'icc, on a surtout droit à des "remark #1445". Lorsqu'on n'a plus
de "remark", généralement, le code est réellement portable.


La on parle de code invalide qui compile directement... c'est quand meme
pas si benin que ca. Ca n'a pas vraiment de rapport avec les warnings,
hein...


Avatar
rixed
On 2007-07-17, Pierre Maurette wrote:
Donc, en bref, qu'est-ce que &(short)i ?


Ca ressemble un peut à la syntaxe d'un compound literal, sauf que bien
sur le type de i n'est pas un type composé.
Peut être une extension d'iCC ?
Non, moi non plus je ne pense pas.

Avatar
Stéphane Zuckerman
On Tue, 17 Jul 2007, Marc Espie wrote:

In article ,
Stéphane Zuckerman wrote:
On Tue, 17 Jul 2007, Marc Espie wrote:

iCC, c'est bien le compilo Intel ? Quand on voit les bugs qu'ils ont
laisse passer dans leurs derniers processeurs, on s'etonne moins du
comportement du compilo...


Il faut relativiser. Lorsqu'on compile avec gcc, il faut nécessairement
faire un -Wall -W -W...
Avec icc, on a l'équivalent d'un -Wall tout de suite. Lorsqu'on active le
-Wall d'icc, on a surtout droit à des "remark #1445". Lorsqu'on n'a plus
de "remark", généralement, le code est réellement portable.


La on parle de code invalide qui compile directement... c'est quand meme
pas si benin que ca. Ca n'a pas vraiment de rapport avec les warnings,
hein...


Je sais bien, mais bon, taper sur icc, je trouve que c'est aussi que taper
sur gcc (les internal errors d'icc, à une époque, c'était pas si dur à
provoquer, je confirme), mais ta réaction est quand même celle qui dit "de
toute manière, intel, processeurs, compilateurs, même combat" (alors que
bon, c'est quand même pas tout à fait la même équipe derrière chaque
projet d'une part, et que les autres compilateurs ne sont pas exempts de
bugs eux-mêmes d'autre part).

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)



Avatar
Charlie Gordon
a écrit dans le message de news:

On 2007-07-17, Pierre Maurette wrote:
Donc, en bref, qu'est-ce que &(short)i ?


Ca ressemble un peut à la syntaxe d'un compound literal, sauf que bien
sur le type de i n'est pas un type composé.
Peut être une extension d'iCC ?
Non, moi non plus je ne pense pas.


C'est un archaisme qui devrait etre equivalent à (short*)&i, mais qui est
interdit depuis que les organismes normateurs on précisé la notion de
lvalue.
En tous cas, c'est totalement non portable de faire prendre des int pour des
shorts à la fonction foo. La taille de ces deux entiers est probablement
différente, enn particulier sur des architectures courantes, les contraintes
d'alignement sont différentes aussi (bien que cela ne pose pas de problème
dans le cas présent et que les architectures courantes s'accommodent sans se
plaindre de défauts en la matière) et l'endianness bien entendu rend la
manupulation d'une partie d'un entier non portable puisque d'une
architecture à l'autre, les partie manupulée n'est pas la même.

Par conséquent et comme Pierre l'a bien souligné, seul le cas 4) a un sens :
le recours à un temporaire explicite du bon type.

Chqrlie.


Avatar
Xavier Roche
foo((short*)&i); // cas 2
- Le cas 2 n'est pas portable.


On peut pas aussi avoir de bugs en cas d'optimisation ("aliasing" strict) ?

Avatar
espie
In article <f7iumt$u13$,
Xavier Roche wrote:
foo((short*)&i); // cas 2
- Le cas 2 n'est pas portable.


On peut pas aussi avoir de bugs en cas d'optimisation ("aliasing" strict) ?


Si, bien sur.


Avatar
rixed
On 2007-07-17, Charlie Gordon wrote:
a écrit dans le message de news:

On 2007-07-17, Pierre Maurette wrote:
Donc, en bref, qu'est-ce que &(short)i ?


Ca ressemble un peut à la syntaxe d'un compound literal, sauf que bien
sur le type de i n'est pas un type composé.
Peut être une extension d'iCC ?
Non, moi non plus je ne pense pas.


C'est un archaisme qui devrait etre equivalent à (short*)&i, mais qui est
interdit depuis que les organismes normateurs on précisé la notion de
lvalue.
En tous cas, c'est totalement non portable de faire prendre des int pour des
shorts à la fonction foo. La taille de ces deux entiers est probablement
différente, enn particulier sur des architectures courantes, les contraintes
d'alignement sont différentes aussi (bien que cela ne pose pas de problème
dans le cas présent et que les architectures courantes s'accommodent sans se
plaindre de défauts en la matière) et l'endianness bien entendu rend la
manupulation d'une partie d'un entier non portable puisque d'une
architecture à l'autre, les partie manupulée n'est pas la même.

Par conséquent et comme Pierre l'a bien souligné, seul le cas 4) a un sens :
le recours à un temporaire explicite du bon type.


Et pourquoi pas ceci, puisqu'on parlait de compound literal :

foo((short []){ i });

C'est valide, et ça a l'avantage de ne pas introduire de "tmp".



1 2