compilation 32/64 bits

compilation 32/64 bits - C - Programmation

Marsh Posté le 07-05-2009 à 19:13:56    

Bonjour,  
 
J'ai une sortie différente selon que je compile sous environnement 32 bits ou sous environnement 64 bits.
 
Soit la fonction suivante :
 

Code :
  1. void write(char *file, int team)
  2. {
  3. int fd;
  4. char* buffer = (char*)malloc(sizeof(char)*256) ;
  5. memset(buffer,0,256) ;
  6. if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0744)) == -1) {
  7.     fprintf (stderr, "Erreur en ouverture.\n" ) ;
  8.     exit(0) ;
  9. }
  10. else
  11. {
  12.  printf("PID :%d Equipe :%d\n", getpid(), team);
  13.  snprintf (buffer, sizeof(buffer)+1,"%d\n%d\n", getpid(), team);
  14.  printf("Buffer : %s Sizeofbuffer : %d\n", buffer, sizeof(buffer)+1);
  15.  write(fd, buffer, strlen(buffer));
  16.  free(buffer) ;
  17.  close (fd) ;
  18.  printf("Ecriture réussie sur le fichier %s\n", file);
  19. }
  20. }


 
Le fichier créé porte le nom G500. J'y inscrit le numéro du PID et un numéro d'équipe.
 
Sous 32 bits, la sortie est la suivante :
 
PID :7931 Equipe :22
Buffer : 7931 Sizeofbuffer : 5
Ecriture réussie sur le fichier /tmp/G500
$ cat /tmp/F0678
7931ubuntu@ubuntu~/Projet$  
 
La compilation se passe sans erreur mais la taille du buffer ne permet pas d'écrire les 2 données. Seule la taille du PID est inscrite dans le fichier.
 
Sous 64 bits, la sortie est la suivante :
 
Buffer : 19624
22 Sizeofbuffer : 9
Ecriture réussie sur le fichier /tmp/F0255$ cat /tmp/F0255
19624
22ubuntu@ubuntu~/Projet$  
 
La compilation génère cette erreur sur la ligne : snprintf (buffer...
attention : format ‘%d’ expects type ‘int’, but argument 3 has type ‘long unsigned int’
 
Merci pour vos contributions et votre regard éclairé.


Message édité par sneakz le 07-05-2009 à 19:15:14
Reply

Marsh Posté le 07-05-2009 à 19:13:56   

Reply

Marsh Posté le 07-05-2009 à 19:18:49    

Ta ligne 14 est fausse :

Code :
  1. snprintf (buffer, sizeof(buffer)+1,"%d\n%d\n", getpid(), team);


 
Ton sizeof mesure la taille de ta variable, qui est un pointeur. Taille qui dépend donc de l'archie 32 ou 64bits.
 
La taille de ton buffer est de 256, ton écrit simplement :

Code :
  1. snprintf (buffer, 256,"%d\n%d\n", getpid(), team);


 
(idéalement avec un #define ça serait mieux).

Reply

Marsh Posté le 07-05-2009 à 19:28:20    

Merci tpierron pour cette réponse précise et rapide.
Si j'ai bien compris, j'ai tout intérêt à définir une taille fixe. Cela me permettra en outre d'assurer une compatibilité avec les 2 environnements. (?)
 
Pourquoi ai-je ce message d'alerte sous 64 et pas sur 32 ?
 
attention : format ‘%d’ expects type ‘int’, but argument 3 has type ‘long unsigned int’ sur la ligne 14 ?


Message édité par sneakz le 07-05-2009 à 19:30:13
Reply

Marsh Posté le 07-05-2009 à 20:03:22    

Franchement tu te prends sans doute la tête pour rien avec ton code. Je ferais un truc du genre :
 

Code :
  1. void write(char *file, int team)
  2. {
  3.     FILE * out = fopen(file, "wb" );
  4.     if (out)
  5.     {
  6.         fprintf(stderr, "PID :%d Equipe :%d\n", getpid(), team);
  7.         fprintf(out, "%d\n%d\n", getpid(), team);
  8.         fclose(out);
  9.     }
  10.     else perror(file);
  11. }


 
Sinon ton warning vient du fait que sizeof() renvoit un type size_t qui devrait être affiché avec un format %z si ma mémoire est bonne. Ah ouais, c'est une extension C99, je parie que ça ne fonctionnera pas avec la mscvrt.
 

Reply

Marsh Posté le 07-05-2009 à 20:19:08    

Ok merci bien

Reply

Marsh Posté le 08-05-2009 à 18:21:35    

Merci bien pour ce complément d'infos mais j'ai le même soucis avec ce code :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <signal.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <ctype.h>
  9. #define SIZE 1024
  10. #define BUF 256
  11. int main(int argc, char **argv)
  12. {
  13.   int pfd[2];
  14.   int nread;
  15.   int number, n;
  16.   int pid;
  17.   char buf[SIZE];
  18.   if (pipe(pfd) == -1)
  19.   {
  20.     perror("pipe failed" );
  21.     exit(1);
  22.   }
  23.   if ((pid = fork()) < 0)
  24.   {
  25.     perror("fork failed" );
  26.     exit(2);
  27.   }
  28.   if (pid == 0)
  29.   {
  30.     /* child */
  31.     close(pfd[1]);
  32.     while ((nread = read(pfd[0], buf, SIZE)) != 0)
  33.      printf("Number %s\n", buf);
  34.     close(pfd[0]);
  35.   } else {
  36.     /* parent */
  37.     close(pfd[0]);
  38.    
  39.     for (n = 0; n < 5; n++)
  40.     {
  41.      number = (rand() % 999) + 1;
  42.      snprintf (buf, BUF,"%d", number);
  43.      write(pfd[1], buf, strlen(buf)+1); 
  44.     }
  45.     close(pfd[1]);
  46.   }
  47.   exit(0);
  48. }


 
Sous l'architecture 64, ma sortie est :
 
Number 479
Number 665
Number 154
Number 269
Number 501
 
Sous l'architecture 32, ma sortie est :
 
Number 479
 
Je ne comprends pas.

Reply

Marsh Posté le 08-05-2009 à 19:25:24    

Ton problème ici est un problème d'ordonancement, indépendant d'une architecture 32 ou 64bits.
 
Quand tu écris quelque chose dans un pipe, tu n'as aucunne garantie que tu vas lire la même quantité à l'autre bout.
 
Affiche la valeur de nread, une coïncidence fait que sur l'archi 32bits tu recoies les 5 write d'un coup, et sur le 64bits, tu les recoies un à un.

Reply

Marsh Posté le 08-05-2009 à 20:22:18    

Merci encore tpierron pour cette analyse.
 
nread = 4 sous 64 bits  
nread = 20 sous 32 bits
 
Quand j'ai dit cela, j'ai tout dit !! :)
 
Mon objectif est de passer dans le tube une multiple de nombres choisis de façon aléatoire.


Message édité par sneakz le 08-05-2009 à 20:25:35
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed