Newsgroup: it.comp.lang.c++
Titolo: perchè non funziona ??

char *stringa = "Rosso! \n";
void main(void)
{
    printf(stringa);                // visualizza rosso
    *(stringa + 3) = 'p';
    printf(stringa);                // visualizza rospo
}
N.B.  questo č un esempio tratto da un manuale

}
Qualche precisazione :
La funzione main() deve avere un valore di ritorno int (non void) e,
in secondo luogo, in alcuni casi, non e' possibile modificare il
literal stringa costante con cui si inizializza il puntatore.
Se programmi in C++, poi, non e' necessario scrivere "void" tra le
parentesi.
In ogni caso, il seguente codice funziona (compilato con Borland C++
Builder 5) :
#include <stdio.h>
char *stringa = "pippo\n" ;
int main()
{
    printf( stringa ) ;
    *(stringa+3) = 's' ;
    printf( stringa ) ;
    return 0 ;
}
--
Andrea Laforgia (UIN 87230455)
----------------------------------------------------------
Non scrivetemi per e-mail, se non richiesto espressamente.
No replies in private e-mail, unless explicitly requested.
----------------------------------------------------------


In C++ una "string literal" è di tipo const char, quindi non si può
modificare.
char* stringa = "Rosso! \n";
stringa[3] = 'p';  // undefined
Se vuoi fare quello che vuoi, devi prima copiare la stringa in un array.

Se vuoi fare quello che vuoi, devi prima copiare la stringa in un array.
Concordo.


sollevare un errore in fase di compilazione.
Per questioni storiche un literal e' un array di char che
pero' non e' ammesso modificare (anche se NON si tratta di un
array di const char). La ragione di questa scelta e' che
altrimenti non sarebbe legale in C++ usare cose come:
    char *p="Andrea";
e questo tipo di costrutto e' usato in milioni di linee di
codice C e C++ esistenti.
Il compilatore non e' pero' normalmente cosi' furbo da
capire che si sta cercando di modificare una "di fatto"
costante attraverso un puntatore a non-const e questo
comporta che scrivere:
    "andrea"[0]='A';
non genera nessun warning ma e' "undefined" e su molti
sistemi provoca un crash al momento dell'esecuzione (in
quanto i literal finiscono in un segmento read-only).
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

[CUT]
Lo Stroustrup dice:
"The type of a string literal is 'array of the appropriate number of
const
 characters'.
 A string literal can be assigned to char*. This is allowed ...
(for compatibility)".
Manlio Perillo

Grazie per le risposte, ma volevo solo precisare che ho provato lo stesso
codice con windows ( bcb 3 ) e funziona, ma adesso sto usando Linux, e li
non c'č mezzo di farlo funzionare,
Non sapevo che i compilatori si comportavano in maniera diversa !  :-(
Grazie ancora
Diego

(for compatibility)".
Interessante. Quando ho letto il posting originale stavo per
rispondere quello che credevo essere la cosa corretta; ovvero
che una string literal fosse un non-const char * che puntava
ad un const char array.
Prima di rispondere pero' ho fatto qualche verifica e ho
scoperto che questo e' semplicemente falso visto che
sizeof("Andrea") non restituisce il size di un pointer ma
il size di un array di 7 caratteri (ebbene si'... confesso
di non aver mai usato in vita mia sizeof("...") in un
programma :D )
A questo punto sono andato a controllare lo standard (il draft
di Aprile 95) e ho trovato questa frase che mi sembrava
lasciare pochi dubbi:
  2.9.4 [ lex/string ]
  ...
  1  A string literal is a sequence of characters (as
     defined in 2.9.2) surrounded by double quotes,
     optionally beginning with the letter L, as in "..." or
     L"...".
 
   * A string literal that does not begin with L has
   * type “array of n char” and static storage duration (3.7),
   * where n is the size of the string as defined below, and
   * is initialized with the given characters.
     Whether all string literals are distinct (that is, are
     stored in nonoverlapping objects) is implementation
     defined.
   * The effect of attempting to modify a string literal
   * is undefined.
{ Ho segnato con un asterisco dove viene detto che un literal
  e' un array di char (senza const) e dove viene detto che non
  e' ammesso modificarne il contenuto }
Quindi ho effettuato il posting su quello che credevo essere
corretto.
Verificando pero' quello che dici sono andato a controllare
sull'ultimo draft pubblico disponibile (Dicembre 1996) ed
effettivamente ora la dicitura e' "array of n const char".
Io usavo la versione 95 perche' e' molto piu' comoda (un unico
PDF invece di una infinita' di file html) ma credo che ora
daro' questi dannati $18 all'ISO per avere lo standard
definitivo visto che (anche per altre questioni) sembra che
le diversita' fra il draft pubblico e lo standard non siano
insignificanti (come invece appaiono essere in questo caso).
Certamente la gestione dei literal e' comunque abbastanza
"anomala"; se si scrive
    const char x[] = "Andrea";
    char *s=x;
si ottiene un errore/warning sulla perdita di const, mentre la
cosa non avviene con
    char *s="Andrea";
Quindi certamente se "Andrea" e' un array di const char non
e' pero' la stessa cosa che si ottiene dichiarando un array di
const char in modo classico (la promozione a puntatore per un
array di n const char ottenuto con un literal si perde
misteriosamente l'attributo const mentre la cosa non succede
per un "normale" array di const char).
Provero' a cercare di capire meglio come questa diversita' e'
descritta nello standard.
In ogni caso onestamente mi sembrava piu' "pulita" la definizione
data nel draft Aprile 95 (anche se come ripeto la differenza
e' forse piu' formale che reale, a meno che si possa scrivere
un frammento di codice che secondo la vecchia definizione deve
avere un comportamento e che secondo la piu' recente ne deve
avere uno diverso).
A questo punto mi sorge anche un dubbio: secondo lo standard
                    "andrea"[0]='A';
richiede l'emissione di un messaggio diagnostico in fase
di compilazione o no ?
Ringrazio per la precisazione
(e per i dubbi che mi ha generato :D )



Mi sembra che lo Stroustrup lo dica nel suo libro ma non riesco a
trovare in che capitolo.
Comunque ho provato con il KAI C++ (con l'opzione --strict) e
mi da un errore: "expression must be a modifiable lvalue"
Manlio Perillo