OVH Cloud OVH Cloud

htonl - faut-il convertir?

5 réponses
Avatar
Shamil
j'ai un tampon de données à envoyer à une machine distante (a priori je ne
connais pas l'archi du proc). Ce tampon contien des entiers et une chaine
de caractères.

char *buffer;
int size;

//some code

msend(buffer,size);

int
msend(void *buffer,int size){
uint32_t *tmp;
tmp=(uint32_t *)buffer; <======== il y aura pas un problème d'alignement?
for(...)
tmp[i]=htonl(tmp[i]);
//sending ...
}



--
Virtuellement votre

5 réponses

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Shamil wrote:

j'ai un tampon de données à envoyer à une machine distante (a priori je ne
connais pas l'archi du proc). Ce tampon contien des entiers et une chaine
de caractères.

char *buffer;
int size;

//some code

msend(buffer,size);

int
msend(void *buffer,int size){
uint32_t *tmp;
tmp=(uint32_t *)buffer; <======== il y aura pas un problème d'alignement?


Peut être. C'est à toi de spécifier les données dans le buffer de façon à ce
qu'il n'y ait pas de problème (adresse paire ou multiple de 4, ça dépend des
contraintes d'architecture). Sinon, il faut faire la conversion "à la main"
byte par byte.

for(...)
tmp[i]=htonl(tmp[i]);
//sending ...
}



--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Yves ROMAN

j'ai un tampon de données à envoyer à une machine distante (a priori je ne
connais pas l'archi du proc). Ce tampon contien des entiers et une chaine
de caractères.

char *buffer;
int size;

//some code

msend(buffer,size);

int
msend(void *buffer,int size){
uint32_t *tmp;
tmp=(uint32_t *)buffer; <======== il y aura pas un problème d'alignement?


Peut-être : ca dépend comment a été défini/alloué buffer.
Ce n'est pas ici que se produira le plantage eventuel, mais a l'utilisation de
*tmp
Pour etre sur que ca passe dans tous les cas, en utilisant htonl pour ne pas
avoir a se préoccuper du type de processeur utilisé faut passer par un
intermediaire bien aligné :
uint32_t tmp2

for(...)
tmp[i]=htonl(tmp[i]);
et ici faire plutot

{
memcpy(&tmp2,tmp+i,sizeof tmp2) ;
tmp2 = htonl(tmp2) ;
memcpy(tmp+i,&tmp2,sizeof tmp2) ;
}

//sending ...
}



Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Shamil wrote:

D'apres FBI vous, Emmanuel Delahaye, avez écrit:


Peut être. C'est à toi de spécifier les données dans le buffer de
façon à ce qu'il n'y ait pas de problème (adresse paire ou multiple
de 4, ça dépend des contraintes d'architecture).


char *buffer=(char *)calloc(sizeof(char),BUFFER_SIZE);


sizeof(char) vaut 1 par définition.

Inutile de compliquer le codage:

char *buffer = calloc(1, BUFFER_SIZE);

ou

char *buffer = calloc(sizeof *buffer, BUFFER_SIZE);

ici buffer peut avoir n'importe quelle adrèsse - paire ou impaire, alors
après le cast


Non. La norme précise qu'un *alloc() retourne obligatoirement une adresse
correctement alignée pour une architecture donnée quelque soit le type.

uint32_t *tmp;
tmp=(uint32_t *)buffer;

si l'adresse du buffer est paire, alors ok, si non tmp pointe sur
l'adresse vosine.


Non. Le cast ne va pas changer l'adresse. Puisque 'buffer' est bien aligné
(donné par un *alloc()), le cast est valide. Il n'y a aucun risque.

<pas de problème, donc snip>

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Avatar
Yves ROMAN

D'apres FBI vous, Emmanuel Delahaye, avez écrit:

Peut être. C'est à toi de spécifier les données dans le buffer de
façon à ce qu'il n'y ait pas de problème (adresse paire ou multiple
de 4, ça dépend des contraintes d'architecture).


char *buffer=(char *)calloc(sizeof(char),BUFFER_SIZE);

ici buffer peut avoir n'importe quelle adrèsse - paire ou impaire, alors
après le cast



Il me semble que (cm)alloc renvoient une adresse alignée :
malloc() and free() provide a simple general-purpose memory
allocation package. malloc() returns a pointer to a block
of at least size bytes suitably aligned for any use.


Avatar
Richard Delorme

Non. La norme précise qu'un *alloc() retourne obligatoirement une adresse
correctement alignée pour une architecture donnée quelque soit le type.


Reste à définir correctement. Dans des documentations d'un fabricant de
processeurs et de compilateurs C/C++, on trouve ce morceau de code :

/* make newp a pointer to a 64 bit aligned array */
/* of NUM_ELEMENTS 64-bit elements */

double *p, *newp;

p = (double*)malloc(sizeof(double)*(NUM_ELEMENTS+1));
newp = (p+7) & (~0x7);

qui aligne newp « de manière appropriée », pour certaines architectures de
ce fabricant. Je suppose donc, que dans certains cas, on doit avoir besoin
de réaligner le pointeur issu de malloc.

--
Richard