Je n'y avais pas fait attention avant, mais read renvoie -1 dans certains cas d'erreur (SUSv3 précise plusieurs cas). Dans ce cas, la valeur -1 est affectée à byte_lu (qui est signé donc il n'y a pas de problème) puis, -1 étant non nul, la condittion de ton while est vraie. Le write est donc exécuté.
Sauf que write attend un troisième argument de type size_t, et que tu lui donnes la valeur-1. size_t étant non signé, la conversion se fait modulo la valeur maximale représentable par ce type +1, soit SIZE_MAX + 1. write reçoit donc la valeur SIZE_MAX (i.e. SIZEMAX + 1 - 1). write va donc essayer de lire autant d'octets dans ton tableau pour les écrire... D'où un comportement indéfini par :
- lecture de données non initialisées si c'est le tout premier appel à read qui plante ;
- et débordement de tableau dans le cas quasi-certain où SIZE_MAX est supérieur à 1024.
A part ça, question de style, je place toujours les accolades autour des blocs if, else, while... Surtout, quand le bloc d'un if est entre accolades, je mets les accolades aussi autour du bloc else (et réciproquement), même si un des blocs ne fait qu'une ligne. Je dis ça surtout par rapport à ton : if (fd == -1)
perror("open: ");
else
{
/* ... */
}
[^] # Re: ta solution ?
Posté par alf . En réponse au message programme c qui émule la commande cat (solution trouvée hipipip houraaaaaaaaaaaa). Évalué à 2.
Sauf que write attend un troisième argument de type size_t, et que tu lui donnes la valeur-1. size_t étant non signé, la conversion se fait modulo la valeur maximale représentable par ce type +1, soit SIZE_MAX + 1. write reçoit donc la valeur SIZE_MAX (i.e. SIZEMAX + 1 - 1). write va donc essayer de lire autant d'octets dans ton tableau pour les écrire... D'où un comportement indéfini par :
- lecture de données non initialisées si c'est le tout premier appel à read qui plante ;
- et débordement de tableau dans le cas quasi-certain où SIZE_MAX est supérieur à 1024.
A part ça, question de style, je place toujours les accolades autour des blocs if, else, while... Surtout, quand le bloc d'un if est entre accolades, je mets les accolades aussi autour du bloc else (et réciproquement), même si un des blocs ne fait qu'une ligne. Je dis ça surtout par rapport à ton :
if (fd == -1)
perror("open: ");
else
{
/* ... */
}