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

cast pointeur

7 réponses
Avatar
Pascal
Bonjour,

J'ai la strucutre suivante

typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;

J'ai la fonction suivante

void titi (BYTE *p)
{
traitement avec p
}

Seulement quand je fais titi(&toto) j'ai un warning du compilo ce qui est
normal.

En fait je veux pointer sur le début de ma structure et la parcourir d'octet
en octet. Comment puis je faire sans avoir de warning?
Une sorte de cast?

Merci

7 réponses

Avatar
Pascal
merci

J'ai oublié de précisé que apres je fais

toto_t uneautrevariable...



typedef struct toto_s
{
BYTE val1,val2;
WORD val3;
} toto_t;


void titi (toto_t * p)
{
BYTE * p_byte = (BYTE*)p; /* <--- c'est la le cast */
etc...
}

note que toto_t est un typedef, pas une variable. Par conséquent, la
notation &toto_t ne signifie pas grand chose.

AG.


Avatar
AG
Pascal wrote:
Bonjour,

J'ai la strucutre suivante

typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;

J'ai la fonction suivante

void titi (BYTE *p)
{
traitement avec p
}

Seulement quand je fais titi(&toto) j'ai un warning du compilo ce qui est
normal.

En fait je veux pointer sur le début de ma structure et la parcourir d'octet
en octet. Comment puis je faire sans avoir de warning?
Une sorte de cast?


typedef struct toto_s
{
BYTE val1,val2;
WORD val3;
} toto_t;


void titi (toto_t * p)
{
BYTE * p_byte = (BYTE*)p; /* <--- c'est la le cast */
etc...
}

note que toto_t est un typedef, pas une variable. Par conséquent, la
notation &toto_t ne signifie pas grand chose.

AG.

Avatar
Emmanuel Delahaye
Pascal wrote on 29/04/05 :
typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;


(en admettant que les types non standards BYTE et WORD sont définis...)

void titi (BYTE *p)
{
traitement avec p
}

quand je fais titi(&toto) j'ai un warning du compilo ce qui est
normal.


Oui, car BYTE* n'est pas compatible avec toto*.

En fait je veux pointer sur le début de ma structure et la parcourir d'octet
en octet. Comment puis je faire sans avoir de warning?


Un paramètre de type void* pour 'anonymiser l'adresse passée. Un
pointeur local de type BYTE* pour le parcours.

Par exemple:

http://mapage.noos.fr/emdel/clib.htm
Module SYS
Fonction SYS_dump()

(Je suis près à parier que c'est exactement ce que tu veux faire!)

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"

Avatar
Harpo
Pascal wrote:

Bonjour,

J'ai la strucutre suivante

typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;

J'ai la fonction suivante

void titi (BYTE *p)
{
traitement avec p
}

Seulement quand je fais titi(&toto) j'ai un warning du compilo ce qui
est normal.


Il est même étonnant qu'il y en ait qu'un seul et pas d'erreur.
toto est un type non une variable.
Le C ne permet pas d'accéder aux types pendant l'éxécution.

pour définir ensuite une variable, faire ensuite par exemple :

toto monToto ; // définit la variable monToto de type toto


En fait je veux pointer sur le début de ma structure et la parcourir
d'octet en octet. Comment puis je faire sans avoir de warning?
Une sorte de cast?


Il est possible que ce ne soit pas une idée excellente, mais on peut
tout faire.

char * p ;
int i ;

p = ( char * ) & monToto ;
for ( i = sizeof( monToto ) ; i-- ; p++ )
{
// on traite le char pointé par p
*p = i ; // par exemple pour aller decrescendo
}

Je ne suis pas allé jusqu'à compiler, il n'est pas non plus certain
(c'est un euphémisme voire une début de troll sur fclc) que tous les
char soient des octets, mais c'est dans ce genre qu'il peut y avoir une
solution.
L'octet est une question d'implémentation sous-jacente, il est en
général peu avisé de s'en soucier.

Qu'est-ce que vous voulez faire avec ça ?

Avatar
Yves ROMAN

Bonjour,

J'ai la strucutre suivante

typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;

J'ai la fonction suivante

void titi (BYTE *p)
{
traitement avec p
}

Seulement quand je fais titi(&toto) j'ai un warning du compilo ce qui est
normal.

En fait je veux pointer sur le début de ma structure et la parcourir d'octet
en octet. Comment puis je faire sans avoir de warning?
Une sorte de cast?



Pourquoi pas
titi((BYTE *)&toto) ;
ou
titi(&toto.val1) ;

Avatar
Pierre Maurette
Bonjour,

J'ai la strucutre suivante

typedef struct
{
BYTE val1,val2,
WORD val3;
etc....
}toto;

J'ai la fonction suivante

void titi (BYTE *p)
{
traitement avec p
}

Seulement quand je fais titi(&toto) j'ai un warning du compilo ce qui est
normal.

En fait je veux pointer sur le début de ma structure et la parcourir d'octet
en octet. Comment puis je faire sans avoir de warning?
Une sorte de cast?
*

On admet l'équivalence BYTE - octet, on peut par exemple penser que
vous êtes sous Windows.

On part du code corrigé par AG:
typedef struct toto_s
{
BYTE val1,val2;
WORD val3;
} toto_t;

et de votre code:

void titi (BYTE *p)
{
/* traitement avec p */
}

En plus des autres solutions proposées, et pour rester au plus près de
votre question, c'est bien un cast (pas une sorte de) qu'il faut ici:
titi((BYTE*)&toto_s);

<oublier si confusant>
Dans la lignée de ce qu'écrit Emmanuel, on peut *mentalement* passer
par void*:
titi((BYTE*)((void*)&toto_s));
Pour moi, void* est le type "adresse". Dire que tout autre pointeur
*est* une adresse est à mon sens dangeureux. Je préfère dire qu'un
pointeur peut être initialisé par le résultat de l'opérateur adresse &.
</oublier si confusant>

Tout ceci n'est possible, *pour val1*, qu'en vertu du fait que la norme
dit que le pointeur vers une structure "se compare égal" avec le
pointeur vers son premier élément. Ce qui se dit plus simplement: il
n'y a pas de padding avant le premier élément d'une structure.

En revanche, je suis inquiet quand je lis: "et la parcourir d'octet en
octet". Non pas à cause du mot octet, mais à cause du padding possible.
Si vous êtes sous Windows et que vous remplacez WORD par DWORD ou int,
vous pourriez avoir une surprise. A moins que le but soit justement
"d'étudier le padding".

Donc, si vous parcourez la structure entière octet par octe, il vous
faut le faire sur la base de sizeof(toto_t), et si vous voulez accéder
aux éléments de la structure autres que le premier, il faut voir du
coté de offsetof(toto_t, élément). Mais les opérateurs d'indirection .
et -> sont faits pour ça.

--
Pierre

Avatar
Pascal
Merci à tous :o)