Newsgroup: it.comp.lang.c++
Titolo: Crash, questo sconosciuto

Ciao a tutti,
il motivo che mi induce a postare la presente e', oltre alla curiosita',
l'apparente inspiegabilita' della cosa.
Dunque, ho una cosa del genere :
class str2ldbl {
    //...
  public:
    //...
    str2ldbl(const std::string &s);
    operator long double();
};
//....
class Field { /*...*/ };
long double Field::GetFloatingValue()
{
    try {
       return str2ldbl(m_data);
    }
    catch(str2ldbl::error x) {
       throw ConversionError(x.what);
    }
}
//... Ometto molto codice non rilevante
int main()
{
   Record record;
   record.AddField("Alex","AbCdEfGhIjKlM");
   record.AddField("Domenico","2.3142e24");
   record.AddField("Silvia", "21/12/1991");
   std::cout<<record.GetField("Domenico").GetFloatingValue();
}
Avvio il programmino di test e... BUUM! Segmentation fault a livello di
Field::GetFloatingValue() !!!
Se in GetFloatingValue, a "return str2ldbl(m_data)" sostituisco "long double
tmp = str2ldbl(m_data); return tmp", il problema e' risolto...
Quello che mi chiedo e': in che punto commetto l'errore?
1) Passo std::string a str2ldbl;
2) str2ldbl calcola automaticamente il risultato;
3) "return str2ldbl" sfrutta l'operatore di conversione
4) BUM
Ho eseguito test di tutti i tipi su str2ldbl, ma non vuole saperne di crashare,
invece basta dare un semplice "return str2ldbl" per mandare in tilt il
programma... non riesco a spiegarmelo. C'entra forse qualcosa con l'operatore
di conversione a long double? Sarebbe assurdo!
Ciao a tutti
Domenico Barra

Ciao Domenico,
potresti postare come hai implementato il costruttore e  l´operatore?
Magari potrebbe essere rilevante
class str2ldbl {
    //...
  public:
    //...
    str2ldbl(const std::string &s);
    ^
    operator long double();
    ^
};
Grazie
Mauro


Dovresti sopportare un po' di codice, se postassi il costruttore... in quanto
da solo non avrebbe senso.
Tuttavia, non credo sia colpa del costruttore in quanto č testato e
stratestato, e poi il suo lavoro č finito da un po', quando richiami
l'operatore di conversione; infine: traffica un po' coi puntatori, ma non fa
niente di "sporco", e termina in pace. Dopo la sua terminazione, non si
"gioca" piů coi puntatori.
Non credo, per contro, che avendo una var. membro "long double m_val", e
implementando un operatore del genere:
operator long double() { return m_val; }
ci possa essere qualcosa di compromettente.
Strano, piů guardo, piů mi convinco che devo cercare l'errore da qualche altra
parte, ma dove? Con quel semplicissimo work-around della variabile temporanea,
tutto fila liscio...
Ciao
Domenico Barra


Scusami Domenico ma non ho capito bene,
quando fai:
long double Field::GetFloatingValue()
{
    try {
       return str2ldbl(m_data);
    }
    catch(str2ldbl::error x) {
       throw ConversionError(x.what);
    }
}
Alla riga dove c´e´ return str2ldbl(m_data);
stai ritornando un valore long double frutto della conversione del tuo
operatore nella classe str2ldbl.
Prima considerazione (ma non penso che sia questo il problema):
siamo sicuri che m_data e´ di tipo string? Altrimenti verra´ chiamato il
costruttore di default penso.
Seconda considerazione:
questa riga --> return str2ldbl(m_data); non mi convince perche´ il tuo
operatore di conversione agisce quando ha "capito" che quello che deve
ritornare la tua funzione e´ un long double mentre se facessi:
return static_cast<long_double>(str2ldbl(m_data));
forse "capirebbe" prima quello che cé´ da ritornare .
Solo che non so spiegare come mai la seconda soluzione puo´ funzionare
mentre la prima no.
Mauro

mentre la prima no.
Non credo proprio sia qui il problema: nel momento in cui tu definisci una
funzione come "funzione che ritorna un long double", dopo l'istruzione return
_deve_ esserci un valore "long double", oppure uno che puo' esservi
implicitamente convertito, o un cast esplicito, altrimenti il compilatore si
arrabbia. Dunque il compilatore sa che li' io voglio un long double, e mi
richiama automaticamente l'operatore di conversione (non si potrebbe
diversamente spiegare il suo "silenzio", ovvero il fatto che non segnala
errori nell'istruzione "return str2ldbl(m_data)").
...
Comincio lontanamente a sospettare che si tratti di una "chicca" del
compilatore, boh, forse troppe variabili temporanee di seguito (la butto li'
senza pensarci troppo). Quando ho tempo provo a vedere come va con altre
piattaforme e compilatori.
Ciao
Domenico Barra

Non e' che fai qualche pasticcio con qualche puntatore, e la variabile
temporanea ha il solo effetto di allungare lo stack?
Ciao,
Nicola

 di conversione a long double? Sarebbe assurdo!
ciao, non è che per caso stai utilizzando Visual C++? Mi pareva di
aver letto tra i bug conosciuti che ci fosse proprio un esempio del
genere in cui il compilatore faceva un mezzo casino. Al massimo, prova
il codice con altri compilatori.

tutto fila liscio...
qualche puntatore vagante? a occhio sembrerebbe una situazione da
undefined behaviour, ma visto che il codice sembra corretto magari in
qualche altro punto del codice scrivi in una zona di memoria non
allocata. Ti consiglio due cose:
1) prova ad isolare il codice che va in crash: cosě sai dove cercare
2) prova a compilarlo anche con altri compilatori: magari ti danno
qualche indicazione piů precisa, oppure la colpa č di un bug della
libreria standard della borland.
Ciao Anto
--
Antonio Cuni, 18 anni, studente
Brainbench Certification: 
Master C++: 4.44, higher than 97% of all previous test takers.
Visual Basic 5: 3.06, higher than 77% of all previous test takers.
http://www.brainbench.com/transcript.jsp?pid=1301688

temporanea ha il solo effetto di allungare lo stack?
E' quello che avevo pensato anch'io, ma al momento non sono riuscito a trovare
"pasticci" coi puntatori, tutto mi sembra in perfetta regola. Certo che se e'
un errore mio (come e' probabile), e' piuttosto "subdolo"!
Ciao
Domenico

libreria standard della borland.
E chi ha parlato di Borland? Lavoro con g++ 2.95.2, che è meglio (anche se la
libstdc++ è un po' vecchiotta... mi toccherà aggiornarla). A proposito,
qualcuno conosce le novità della nuova libstdc++?
Ciao
Domenico Barra

 wrote in message
news:982164977....@news.iol.it...

Scusa ma, hai pensato di provare a compilare sia la versione funzionante e che
usa la variabile locale, sia quella non funzionante che non la usa, e poi andare
a vedere con un debugger cosa cavolo genera il compilatore?
Se e' un baco del compilatore dovresti accorgertene subito. E con un single step
in assembler dovresti anche capire facilmente il vero motivo del crash.
Altrimenti a che servono i debuggers?
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

Altrimenti a che servono i debuggers?
Hai ragione. Purtroppo col gdb (l'unico che ho al momento) non sono molto
pratico (dovrò leggermi la documentazione per benino!). Comunque, il segnale di
Segmentation Fault proviene dal distruttore di std::string. Quello che è buffo
è che io della stringa non vado a modificare proprio niente (tant'è vero che
al costruttore di str2ldbl la passo come const, e vi accedo sempre come const).
Farò un altro tentativo, a questo punto: invece di passare std::string, gli
passerò un array di caratteri, e vedrò cosa succede (penso proprio niente,
visto che SegFault avviene all'interno del distruttore della stringa).
Ciao
Domenico Barra

qualcuno conosce le novità della nuova libstdc++?
scusa, me lo sono sognato. cmq il consiglio e sempre valido: prova a
cambiare compilatore (ad esempio usa il Borland :-)
anto


 qualcuno conosce le novità della nuova libstdc++?
gcc/g++ versione 3 e' sempre previsto RSN - per fine primo quarto
2001; non tratterrei il fiato, pero', visto che si tratta sempre di
free software.  Intanto il gruppo di sviluppo ha congelato la versione
attuale: in pratica il codice viene cambiato solo per aggiungere
documentazione e correggere errori (NON per aggiungere miglioramenti,
per quanto innocui e buoni siano) --- e questo vuol dire che si e' a
buon punto.
L'ultimo snapshot rilasciato (il 5 febbraio; si puo' scaricare da
ftp://ftp.funet.fi/pub/mirrors/sourceware.cygnus.com/pub/gcc/snapshots/2001-02-05/
)
funziona perfettamente con tutto il mio codice (che non e' poco, e che
viene compilato anche con prodotti commerciali come KCC); e sembra
abbastanza stabile.  Quello che si nota subito e' che in presenza di
una grossa mole di templates il tempo di compilazione aumenta di un
bel po' (rispetto alla versione 2.95.2), ma la dimensione
dell'eseguibile diminuisce da un fattore minimo di 2 fino a quasi un
ordine di grandezza (!).
La libreria standard e' ottima, e non sono riuscito a trovare nessuna
discrepanza con l'ANSI/ISO; bisogna esplicitamente richiedere la
libreria versione 3 in fase di configurazione, la vecchia versione 2
e' stata inclusa comunque per compatibilita'.  Tutte le dolenti note
della varsione 2 (stringstreams, iostreams, thread safety, namespace
std) sono scomparse.
Last but not least, e' previsto il rilascio di una 2.95.3 (che completi
la serie delle revisioni 2.95 con la correzione di bugs trovate
durante lo sviluppo della versione 3), contestualmente al rilascio di
gcc 3.x .
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
The instructions said to use Windows 98 or better - so I installed FreeBSD.

 cambiare compilatore (ad esempio usa il Borland :-)
non vorrei sembrare di parte, ma il gcc 2.95.3, con le libstdc++ 3, e' 
quanto di piu' conforme esista per molte piattaforme, e non siamo 
lontani dal comeau.

 lontani dal comeau.
Il gcc 2.95.3 non esiste.  
http://gcc.gnu.org/
 for more.
Per mettere TUTTI i puntini sulle i, il gcc 2.95.2.1 (ultima release
ufficiale del compilatore) e' compatibile con le releases fino alla
2.90.8 di libstdc++ 3; non e' piu' stato compatibile con la release
2.91 della standard library.


 Il gcc 2.95.3 non esiste.  
http://gcc.gnu.org/
 for more.
ohibo', che ti devo dire?
$ gcc -v 
Reading specs from /usr/lib/gcc-lib/i586-linux/2.95.3/specs
gcc version 2.95.3 19991030 
di piu'
$ ls /usr/include/g++*
/usr/include/g++-3:
SFile.h       fstream        pthread_alloc    stl_multimap.h
[...]
sto usando dei fantasmi?-)
(capisco cosa intendi, ma come l'aerodinamica per i calabroni, cio' non 
impedisce alla cosa di funzionare)

 gcc version 2.95.3 19991030 
Vuol dire che qualche casa distributrice di software si e' inventata
una release inesistente per poter dire: "guarda, cicciolino, la casa
[inserisci qui un nome della concorrenza] ti da' una release piu'
vecchia della mia".  Io ho partecipato ai working groups GNU e, il 30
ottobre 1999, l'ultima versione rilasciata era la 2.95.2 (guarda caso,
rilasciata il 24 ottobre 1999, sei giorni prima, come si evince da
http://gcc.gnu.org/releases.html
).
Riporto, per completezza, il testo di 
http://gcc.gnu.org/gcc-2.96.html
:
========================Begin included file
It has come to our attention that some GNU/Linux distributions are
currently shipping with ``GCC 2.96''.
We would like to point out that GCC 2.96 is not a formal GCC release
nor will there ever be such a release. Rather, GCC 2.96 has been the
code- name for our development branch that will eventually become GCC
3.0.
Current snapshots of GCC, and any version labeled 2.96, produce object
files that are not compatible with those produced by either GCC 2.95.2
or the forthcoming GCC 3.0. Therefore, programs built with these
snapshots will not be compatible with any official GCC
release. Actually, C and Fortran code will probably be compatible, but
code in other languages, most notably C++ due to incompatibilities in
symbol encoding (``mangling''), the standard library and the
application binary interface (ABI), is likely to fail in some
way. Static linking against C++ libraries may make a binary more
portable, at the cost of increasing file size and memory use.
To avoid any confusion, we have bumped the version of our current
development branch to GCC 2.97.
Please note that both GCC 2.96 and 2.97 are development versions; we
do not recommend using them for production purposes. Binaries built
using any version of GCC 2.96 or 2.97 will not be portable to systems
based on one of our regular releases.
If you encounter a bug in a compiler labeled 2.96, we suggest you
contact whoever supplied the compiler as we can not support 2.96
versions that were not issued by the GCC team.
Please see 
http://gcc.gnu.org/snapshots.html
 if you want to use our
latest snapshots. We suggest you use 2.95.2 if you are uncertain.
The GCC Steering Committee
========================End included file


 Io ho partecipato ai working groups GNU e [...]
sono contento per te, magari ne avessi io il tempo.

 non so se hai letto l'ultima parte del msg.
Non cambiamo le carte in tavola.
Io ho detto:          "Non esiste una release 2.95.3".
Tu hai detto:         "Si, ce l'ho io".
Io ho detto:          "Pensi di averla ma non ce l'hai".
Non rispondere        "Il gcc che ho io funziona".


 Non rispondere        "Il gcc che ho io funziona".
non era mia intenzione comunicare questo. 
vediamo se cosi va bene
"una mia distribuzione (RH6.2 e altre derivate) ce l'ha una, che non e' 
della 
gnu.org
, ma chiama cosi', va bene e non e' un semplice rebuild"
ok?
senza voler polemizzare, per carita'. 
sulla debian non c'e' :)