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
Stéphane Zuckerman
On Wed, 18 Jul 2007, wrote:

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



C'est valide uniquement en C99 non ?

--
"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, 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".


Et aussi l'inconvénient de ne pas permettre d'accéder au résultat ;-)
dans l'exemple de Pierre Maurette, foo() a un effet de bord sur le short
dont elle prend l'adresse en parametre.

Chqrlie.




Avatar
Antoine Leca
En news:, Pierre Maurette va escriure:
void foo(short* param);
int i;
short temp;
/* ... */
foo(&i); // cas 1
foo((short*)&i); // cas 2
<couic>

- Le cas 2 n'est pas portable. Il ne pourrait être utilisable que dans
un environnement connu,


Oui. Genre arithmétique en complément à 2 et petit-boutien.
Ce qui laisse un petit taux de chute à l'heure actuelle...

(Ou int 16 bits, ou plus généralement short===int, mais là c'est pour faire
savant, pas réaliste.)

[...] en maîtrisant l'implémentation de foo()


Pourquoi ? Si le transtypage à l'appel est valide, le reste doit passer
comme une lettre à la poste.

Bien sûr, il te faut savoir si
void foo(short* param);
signifie bien ce qui est écrit (et décrit), c'est-à-dire un simple paramètre
short de mode out ou in_out; ou si en fait il s'agit plutôt de

void foo(short param[]);
(les deux syntaxes sont idempotentes en C), autrement dit un paramètre
tableau de short... ce qui invaliderait le transtypage...


[...] et avec le risque de se vautrer lors de la réutilisation
de cette fonction.


Comme tous les transtypages. C'est d'ailleurs la raison pour laquelle je
n'aime pas les transtypages, surtout pour s'adapter aux conventions d'appel.


Et dans ces conditions, pourquoi utiliser au départ un
short* et non un void*, hein ?


Pour obliger au transtypage explicite (et donc bénéficier d'un contrôle de
type, certes restreint mais réel) ?


Antoine

Avatar
Antoine Leca
En news:,
va escriure:

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


Les littéraux composés de C99, ce n'est rien d'autre que des "tmp"
anonymes... Alors évidement, c'est équivalent dans le cas d'une utilisation
one shot...

Dans le même genre (inutile ÀMHA), on peut aussi essayer

foo(& (short){ i });


Note qu'ici, c'est équivalent à
{ short temp = i;
foo(&temp);
}

Mais Pierre avait écrit (enlever le commentaire pour un paramètre in_out au
lieu de out)
/*function scope*/
short temp /* = i */ ;
foo(&temp);
i = temp;


Antoine


Avatar
Antoine Leca
En news:f7iumt$u13$, Xavier Roche va escriure:
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) ?


À quoi penses-tu ? Un petit exemple, peut-être ?


Antoine


Avatar
Vincent Lefevre
Dans l'article <f870fe$46t$,
Antoine Leca écrit:

(Ou int 16 bits, ou plus généralement short===int, mais là c'est
pour faire savant, pas réaliste.)


Il y a (avait) pourtant un compilo sous RISC OS (ARM) avec short===int
(ce choix avait été fait parce que les anciens ARM ne supportaient des
lectures/écritures que sur 8 et 32 bits).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Antoine Leca
En news:20070726131509$,
Vincent Lefevre va escriure:
Dans l'article <f870fe$46t$,
Antoine Leca écrit:

(Ou int 16 bits, ou plus généralement short===int, mais là c'est
pour faire savant, pas réaliste.)


Il y a (avait) pourtant un compilo sous RISC OS (ARM) avec short===int
(ce choix avait été fait parce que les anciens ARM ne supportaient des
lectures/écritures que sur 8 et 32 bits).


Oui. Je pensais plutôt au MC68000 en mode 16 bits et aux Cray ou autres
PDP-10, mais ce ne sont pas des cas isolés, évidemment.

Mais je voulais seulement souligner qu'il s'agit de cas marginaux.
Le cas le plus courant où l'hypothèse de Pierre {i == *(short*)&i} tient, ce
sont les machines petit-boutiens (Intel, pour être trivial et réducteur.)


Antoine


Avatar
Erwan David
Vincent Lefevre <vincent+ écrivait :

Dans l'article <f870fe$46t$,
Antoine Leca écrit:

(Ou int 16 bits, ou plus généralement short===int, mais là c'est
pour faire savant, pas réaliste.)


Il y a (avait) pourtant un compilo sous RISC OS (ARM) avec short===int
(ce choix avait été fait parce que les anciens ARM ne supportaient des
lectures/écritures que sur 8 et 32 bits).


J'ai manipulé ça le mois dernier. Et hier l'équivalent sur H8S Hitachi
(compilo Hitachi d'ailleurs).

--
Erwan


Avatar
Erwan David
Vincent Lefevre <vincent+ écrivait :

Dans l'article <f870fe$46t$,
Antoine Leca écrit:

(Ou int 16 bits, ou plus généralement short===int, mais là c'est
pour faire savant, pas réaliste.)


Il y a (avait) pourtant un compilo sous RISC OS (ARM) avec short===int
(ce choix avait été fait parce que les anciens ARM ne supportaient des
lectures/écritures que sur 8 et 32 bits).


J'ai manipulé ça le mois dernier. Et hier l'équivalent sur H8SX Hitachi
(compilo Hitachi d'ailleurs).

--
Erwan


Avatar
Erwan David
"Antoine Leca" écrivait :

En news:,
Erwan David va escriure:
Vincent Lefevre <vincent+ écrivait :

Dans l'article <f870fe$46t$,
Antoine Leca écrit:

(Ou int 16 bits, ou plus généralement short===int, mais là c'est
pour faire savant, pas réaliste.)


Il y a (avait) pourtant un compilo sous RISC OS (ARM) avec
short===int (ce choix avait été fait parce que les anciens ARM ne
supportaient des lectures/écritures que sur 8 et 32 bits).


J'ai manipulé ça le mois dernier. Et hier l'équivalent sur H8SX
Hitachi (compilo Hitachi d'ailleurs).


C'est juste pour ma culture personnelle, mais tu veux dire que le compilo
pour H8SX définit short===int===int32_t ?

Sinon, si c'est la même chose que les autres H8 avec short===int===int16_t,
on retombe dans le cas int 16 bits.


Euh hypothèse 2, j'avais mélangé...


Dans tous les cas, je ne pense pas que programmant pour une telle machine ou
plus généralement pour autre chose qu'une station de bureau ou un serveur
largement répandu, il vous vienne l'idée de laisser traîner des

void foo(short* param);
int i;
/* ... */
foo((short*)&i);

en espérant tranquillement que cela fonctionnera jusqu'à la nuit des
temps... Enfin, j'espère que l'idée fut écartée ;-).


Non, là je sors la kalashnikov...


--
Erwan




1 2