Newsgroup: it.comp.lang.c
Titolo: Caccia all'errore.

Ciao. 
Un esercizio mi chiede di trovare quale errore si nasconde in un 
programma.
L'ho svolto quasi completamente, ma mi è rimasto un dubbio.
Posto qui il codice, l'output e la mia domanda.
INtanto grazie a tutti e ciao 
Bizio.
+++Il codice:
#include <stdio.h>
#include <string.h>
int main(void)
{
 char *p1 = "abc", *p2 = "pacific sea";
 printf("%s %s %s\n", p1, p2, strcat(p1, p2));
 return 0;
}
+++L'output:
abcpacific sea acific sea abcpacific sea
+++La domanda: 
Perché l'output generato dal secondo parametro della funzione printf è 
"acific sea" e non "pacific sea"?
In altre parole, perché la printf modifica anche il valore di p2?
p1 lo modifica per l'effetto di strcat che viene valutata prima di 
procedere alle stampe, ma p2? 

  printf("%s %s %s\n", p1, p2, strcat(p1, p2));
Ci sono almeno 2 errori e mezzo.
1)
non si puo' fare la strcat perche'
p1 non punta ad uno spazio di memoria
abbastanza grande per contenere la
concatenazione di "abc" e "pacific sea".
Quindi facendo la concatenazione si va a sporcare
la memoria e i risultati che si ottengono
sono la qualunque.
2)
se uno definisce stringhe in questo modo
esse di fatto risiedono "dentro" il codice
e in quanto tali non sono modificabili,
(perlomeno con alcuni compilatori)
perche' generalmente il sistema assume
che se un programma sta cercando di modificare
il proprio codice questo e' "male".
Per esempio, una teoricamente innocua (perche' c'e'
spazio abbastanza)
strcpy(p2,p1);
ottiene un bel segmentation fault sulla mia macchina
linux.
2.5)
l'uso di comandi con un effetto laterale come
strcat(p1, p2) e' spesso un errore all'interno di una
chiamata di funzione, perche' il linguaggio non stabilisce
che il compilatore debba privilegiare un ordine
o un altro nella valutazione dei parametri
della funzione. Potrebbe cioe' valutare
prima p1, poi p2, poi la strcat che modifica p1,
o anche viceversa.
E' vero che alla fine si tratta sempre dei puntatori
p1, p2, p1, ma la cosa mi sembra veramente un brutto
esempio di programmazione.
ciao,
g.

> L'ho svolto quasi completamente, ma mi è rimasto un dubbio.
Ecco, questa volta ti ho aiutato perche' ero distratto, ma
la prossima volta posta prima la *tua* soluzione...
g.

 esempio di programmazione.
Questo invece non capisco cosa vuol dire e comunque la storia 
dell'ordine di valutazione è  completamente ininfluente per l' esempio 
in questione.
Giorgio

 in questione.
...facciamo un esempio piu' serio (si fa per dire):
=====
#include <stdio.h>
#include <string.h>
int main(void)
{
         char p1[128] = "a", p2[128] = "b";
         printf("%s - %s - %s\n", p1, p2, strcat(p1, p2));
         return 0;
}
=====
Secondo te, il programma stampera': "a - b - ab" oppure "ab - b - ab" ?
Ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

> in questione.
(precisazione - a scanso di equivoci)
Giorgio, attenzione: non ho detto che tu abbia torto ;)
...anzi, riguardo all'ordine di valutazione che e' ininfluente sull'output, 
hai ragione. Ma mi pare che tu non abbia sostanzialmente capito "il senso" 
di quello che (imprecisamente) ha detto nano bagonghi...


 capito "il senso" di quello che (imprecisamente) ha detto nano bagonghi...
Mea culpa.  Avevo letto troppo in fretta il terzo punto e  ho equivocato 
sul significato :-(
Giorgio

 la prossima volta posta prima la *tua* soluzione...
Ho posto solamente la domanda per ragioni di tempo. 
Pensavo fosse inutile spiegarvi cose che gią sapete molto meglio di me. 
Aiutarmi o meno, rimane comunque una tua scelta insindacabile.
Ciao 
Bizio.