Newsgroup: it.comp.lang.c++
Titolo: Uno sguardo a C++0x

Buon giorno a tutti,
In quest'articolo:
 
http://www.artima.com/cppsource/cpp0x.html
zio Bjarne esplora brevemente quali nuove feature vorrebbe vedere
aggiunte al linguaggio, che dovrebbe diventare standard ISO entro il 2009.
Senza scatenare automaticamente flamewars (deh, facile a dirsi... ;-))
volevo il vostro parere un po' su tutte le feature proposte.
Inoltre: qualcuno inoltre può spiegarmi meglio la faccenda dei
``concepts''? Devono essere utili, ma non sono certo di afferrare il perché.
E ``auto'': pensate sia effettivamente un aiuto a ridurre la prolissità,
o solo fonte di confusione? Io lo vedo come una cosa buona...
Grazie,
-- 
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
------END GEEK CODE BLOCK------

 o solo fonte di confusione? Io lo vedo come una cosa buona...
Devo pensarci. Sicuramente farà scrivere codice più corto.
Tuttavia potrebbe rischiare di fare perdere consapevolezza sui "tipi
veri" degli oggetti. 
Senza dubbio ci sono però fior di occasioni in cui è comodo (tipicamente
dl'esempio del ciclo for)

 che li il check è statico e non è una robba sintattica.
Ovviamente "il check non è statico ma dinamico e non è una robba
sintattica" :))
-- 
non vincono, non vinceranno, non hanno domani
la forza è nel puntello impugnato da oneste fortissime mani

 o solo fonte di confusione? Io lo vedo come una cosa buona...
Ci sono applicazioni dove e' assolutamente indispensabile. Il campo
piu' ovvio e quello degli expression templates, che sono una tecnica
per implementare la lazy evaluation tramite la memorizzazione della
struttura di un'espressione invece del suo valore. Esistono diverse
librerie di calcolo matriciale che si basano su questa tecnica. Il
problema e' che il tipo di un espressione puo' risultare qualcosa come
Vettore<double> v;
TriangSup<double> m;
Prod<Prod<Trasposto<Vettore<double> >, Inversa<TriangSup<double> > >,
         Vettore<double> > risultato = trasp(v) * m * v;
pensa poter scrivere
auto risultato  = trasp(v) * m * v;
figurati poi per espressioni piu' complesse...
Per quanto riguarda invece le aggiunte alla libreria standard molte
delle novita' presentate nel TR1 sono librerie Boost che uso gia' e che
trovo molto utili. Spero poi che il lavoro sul supporto del
multithreading sia completato in tempo e penso che la possibilita' di
avere garbage collection opzionale possa rivelarsi utile.
Ciao,
Nicola

 aggiunte al linguaggio, che dovrebbe diventare standard ISO entro il 2009.
Sono senz'altro utili, ma non vedo ancora un tipo stringa nativo C++, 
eventualmente utilizzabile come il classico array di caratteri con un 
meccanismo di boxing/unboxing automatico come in C# :->
sarò un nostalgico del Pascal, ma trattare con le stringhe come se 
scrivessi in assembler non mi piace, non mi piace e non mi piace :-)
E poi sono pure più lente :-P
Anyway, mi chiedo: ci sono voluti degli anni per avere dei compilatori 
che implementassero il C++98 come si deve, se questo sarà standard nel 
2008-2009 quanto ci vorrà perchè gli strumenti di sviluppo ci si conformino?

 meccanismo di boxing/unboxing automatico come in C# :->
Cos'ha std::string che non va?
Ciao,
Nicola

 Cos'ha std::string che non va?
1) non è esattamente un tipo nativo, e quando cominci a usarlo un pò 
troppo disinvoltamente come se lo fosse te ne accorgi...
2) non ha mai nemmeno sentito parlare di Unicode. Per ora non è un gran 
problema, ma non so se nel 2010 sarà ancora così... una stringa unicode 
non è un semplice array di tipi interi, è una struttura complessa. 
Volerla rappresentare a tutti i costi come array crea problemi, anche 
come array di wchar_t. Meglio a questo punto un tipo apposta, no?

 opzionale possa rivelarsi utile.
Sicuramente io sono troppo "di parte", perché trovo la GC una delle
peggiori assurdità mai concepite (nell'ambito dei linguaggi di
programmazione, ovviamente), ma vedo nell'eventuale introduzione di una
GC anche se opzionela la fine del C++.
Già oggi una buona (maggior?) parte del codice C++ che si vede in giro 
usa impropriamente ereditarietà (del tipo: "se non erediti non è OOP"), 
con grande uso di puntatori nativi (con i loro relativi problemi) ed 
abuso di allocazione dinamica non necessaria, invece di spingere per un
corretto uso del linguaggio questa "javizzazione" mi pare prima di tutto 
un "darla vinta" a chi usa scorrettamente il linguaggio, inoltre mi 
è l'opposto di quanto dica Stroustrup nell'articolo, ossia estendere il 
linguaggio per scopi che possono essere ottenuti senza problemi con 
l'uso di adeguate librerie.
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 come array di wchar_t. Meglio a questo punto un tipo apposta, no?
Cosa dovrebbe fare questo tipo apposta che una std::wstring non fa?


 ma una stringa *è* una sequenza di caratteri.
in unicode un carattere != 1 char, e perdipiu' dovrebbe avere lunghezza
variabile
-- 
         Quante sono le persone
che sanno leggere il codice esadecimale,
        se ci sono de11e persone
che sanno leggere il codice esadecimale?

 e perdipiu' dovrebbe avere lunghezza variabile
Dipende, non necessariamente.


 pdei linguaggi di rogrammazione, ovviamente)
Questa è una posizione indifendibile. Dire che la GC non è adatta a
tutti i contesti è corretto e sacrosanto, ma dire che è un'assurdità...
[ sostanzialmente vuole dire giocarsi praticamente tutti i linguaggi
interpretati di alto livello -- Perl, Python, Ruby, (credo) TCL --,
giocarsi il Lisp, giocarsi il Prolog, Objective Caml  etc... ]
-- 
Python è un linguaggio specialistico nel senso che è specializzato 
nel fare fare le cose rapidamente e bene.

 ma una stringa *è* una sequenza di caratteri.
Vero, ma semplicistico. In unicode la stessa stringa non è univoca :-)
In unicode esistono i "caratteri combinabili": vale a dire che esiste sì 
il carattere tedesco "u con i due puntini", per esempio, ma esistono 
anche il carattere u semplice, il carattere "dieresi" (i due puntini 
sopra) e il carattere speciale "combinatore": quindi la combinazione di 
tre word (caratteri unicode un UCS-2) 'u'+'combinatore'+'dieresi' 
equivale al carattere tedesco 'u' di uber... cioè esiste più di un modo 
per definire alcuni caratteri, il che è bellissimo per chi scrive in 
lingue con un sacco di accenti strani tipo lo svedese, e un bellissimo 
casino per i programmatori che devono confrontare due stringhe o 
calcolarne la lunghezza: e quale lunghezza poi? Quella in memoria o 
quella in caratteri stampati? :-)

 giocarsi il Lisp, giocarsi il Prolog, Objective Caml  etc... ]
Scusami per la risposta concisa ma sono molto di fretta.
Il problema è che l'introduzione di GC automatica fa credere al
programmatore di essersi liberato della necessità di gestire la memoria.
In realtà questo non è vero, il problema si è solo trasformato in
rilasciare i riferimenti.
Dimenticarsi di fare ciò equivale a memory leak esattamente quanto
dimenticarsi di deallocare (con freee o delete) la mamoria in C/C++.
Non ho mai visto tanti memory leak in programmi scritti in C/C++ quanto
in programmi Java (uno tra i linguaggi più usati -purtroppo- per 
applicazioni di una certa dimensione).
Essere costretto a riavviare il PC ogni 15-20 minuti di utilizzo di
certe applicazioni perché arrivano a consumare 400-500 MB di RAM è una
VERGOGNA.
P.S.
Sì, sono furibondo perché sono 2-3 settimane che sto lavorando nelle
condizioni di cui sopra a causa dell'utilizzo (obbligato) congiunto di
Eclipse e Poseidon.



La stringa non deve sapere nulla di tutto ciò, è il locale che si occupa
di questo.


 Eclipse e Poseidon.
Io questo problema non lo ho. Finchè non ordino il gigozzo di ram
aggiuntivo devo usare *o* Eclipse *o* Poseidon. Insieme fanno la danza
del brontosauro fhyyr zvr cnyyvar.


 dimenticarsi di deallocare (con freee o delete) la mamoria in C/C++.
Il riferimento non dovrebbe essere rilasciato automaticamente quando esce di 
scope? Almeno questo è quello che succede in Clipper e suoi successori.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 VERGOGNA.
Non vedo la necessita' di riavviare il sistema per sopperire 
all'eccessivo carico di memoria da parte di un'applicazione.
Non basta riavviare l'applicazione?
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 Non basta riavviare l'applicazione?
Se l'allocazione avviene nello heap, sě...
Se il programma alloca fuori dallo heap, NO...
:-)

 hai esaminato, saresti piu' chiaro.
E' possibilissimo. Basta salvare un secondo riferimento ad un oggetto e 
questo non viene più distrutto automaticamente all'uscita dallo scope 
perchè ancora referenziato altrove. E se per caso ti dimentichi di 
cancellare anche il secondo riferimento è fatta la frittata. Leggi qua...
http://www.theserverside.com/articles/content/J2EEPerformance/Eliminating_memory_leaks.html


Nella pagina indicata si dice:
"Java memory leaks are often caused by saving an object reference in a 
class level collection and forgetting to remove it at the proper time".
Il che, tradotto in italiano e in C++, significa:
"Si verificano dei memory leaks salvando in strutture dati statiche 
puntatori a dati contenuti nello heap, e dimenticandosi di eliminarli
al momento appropriato".
Penso che sia una cattiva tecnica di programmazione salvare dati 
temporanei in strutture dati statiche.
Non mi e' mai capitato di vederla e non immagino casi in cui sia opportuna.


Massimo Soricetti wrote:

Mi risulta che le uniche allocazioni possibili a un programma sono: 
stack, area statica, heap; e che anche lo stack e l'area statica vengono 
riutilizzati dal sistema operativo quando il processo termina.
Quali tipi di allocazioni di memoria permangono dopo che il processo e' 
terminato?


 anche in C++ senza grossi problemi. IMHO.
Una GC di questo tipo in C++ non avrebbe alcun senso in quanto c'è già.
Basta usare uno smart pointer scritto appositamente (senza problemi di
multithreading si scrive in 30 secondi), od usare una delle classi
scritte da qualcun altro (loki::SmartPtr, boost::shared_ptr oppure -ora-
std::tr1::shared_ptr) che gestiscono il problema della concorrenza.
Volendo è possibile usare librerie come Boehm per avere invece un GC di
tipo diverso, ma tutto ciò rende possibile seguire la regola "Prefer
standard library facilities to language extensions" che è uno dei punti
di forza del C++.


 scope? Almeno questo č quello che succede in Clipper e suoi successori.
Sě, ma sono moltissimi i riferimenti che non escono mai di scope.
Pensa ad un'applicazione grafica dove la finestra principale vive per
tutta la durata del processo. Tutti i riferimenti che sono attributi
membro (e sono molti) non escono mai di scope (fino alla terminazione
del processo) quindi se non posti a null dopo il loro uso il GC non puň
deallocare gli oggetti a loro associati (e gli oggetti che questi hanno
allocato se i loro riferimenti non sono stati posti a null, e cosě
via...)
CIao.


 il secondo riferimento è fatta la frittata.
In pratica avresti tutti i dati statici o che non escono mai di scope? Allora 
non si chiama memory leak.


 via...)
No, anche la finestra principale esce di scope alla chiusura dell'applicazione 
e in quel momento è compito del suo distruttore rilasciare tutte le risorse 
allocate. Io francamente non vedo il problema, anche perché uso linguaggi con 
GC da sempre. L'unico vero svantaggio riguarda l'imprevedibilità del momento 
in cui il GC entra in azione (quindi problemi con i programmi realtime). Ma i 
vantaggi, per programmi "normali", sono innumerevoli, secondo me.


 Non basta riavviare l'applicazione?
No. Se termino il processo il sistema recupera la memoria, ma al
successivo avvio (a meno, appunto, di non aver riavviato il SO) se
"la riprende" immediatamente tutta. E questo indifferentemente sotto
Windows, FreeBSD e linux, con JDK 1.5 e 1.6.


 Non mi e' mai capitato di vederla e non immagino casi in cui sia opportuna.
Vedi il mio esempio dell'alro post. Non si tratta di strutture dati
statiche e non è cattiva programmazione, eppure porta a memory leak se
ci dimentica di rilasciare i riferimenti.


 allocate. 
?? Scusa, ma l'hai scritto tu stesso: alla chiusura dell'applicazione.
Se io in C/C++ mi dimentico di fare le free/delete alla chiusura
dell'applicazione il sistema (su tutti i sistemi per PC) si riprende
comunque la memoria. I memory leak si hanno durante la vita
dell'applicazione, non dopo.
La memoria non più in uso *deve* essere recuperata durante la vita del
processo, non alla sua terminazione (di questo se ne occupa il SO).
Ciao.


 non si chiama memory leak.
No, non si tratta di dati statici anche se non escono mai di scope. E si
tratta proprio di memory leak.


 viene *mai* distrutto.
Se veramente succede questo allora è un grave bug del GC di questo linguaggio 
non un difetto dei GC in generale.


 processo, non alla sua terminazione (di questo se ne occupa il SO).
Ma se la finestra principale ha bisogno di risorse è chiaro che queste 
verranno rilasciate solo alla sua chiusura. Non vedo proprio come potrebbe 
essere diversamente.


 non un difetto dei GC in generale.
Bug? Cosě *deve* comportarsi qualunque GC, sarebbe un bug *immenso* se
cosě non fosse.
Il GC, qualunque sia l'algoritmo usato, elimina gli oggetti non piů
raggiungibili, cioé senza riferimenti che puntano ad essi. Se esistono
riferimenti che "riferiscono" un oggetto (come esiste window che punta
al corrispondente oggetto nel caso che ti ho proposto) il GC non puň (e
non *deve* assolutamente) distruggere l'oggetto.
Cosa succederebbe accedendo ad un oggetto tramite un riferimento valido
(non posto a null) se il GC avesse distrutto l'oggetto?


 tratta proprio di memory leak.
Non si può chiamare memory leak l'utilizzo *voluto* di memoria fino alla fine 
dell'applicazione. La memory leak è quando si alloca memoria e ci si dimentica 
di rilasciarla, cosa che non avviene nell'esempio della finestra principale, a 
meno che la relativa classe non abbia un bug proprio in questo aspetto.


 (non posto a null) se il GC avesse distrutto l'oggetto?
No, continuiamo a non capirci: un GC č in grado di intervenire anche dopo che 
la main č terminata. E a questo punto non ci saranno piů riferimenti attivi 
alla finestra principale. E in ogni caso questa non si chiama memory leak ma 
un bug del GC.


 essere diversamente.
Sono sicuro di non essere stato chiaro, quindi cerco di spiegarmi
meglio.
Tornando all'esempio precedente supponiamo io non abbia piů bisogno
dell'oggetto (riferito da) window. Se non pongo window = null il GC non
dealloca la memoria (perché puň capire la mia intenzione di non usare
piů l'oggetto *solo* se io pongo window = null). 
Se anche l'oggetto (puntato da) window ha a sua volta riferimente validi
ad oggetti allocati (i quali conseguentemente non verranno mai piů
usati) il GC, ancora una volta, non puň deallocare questi oggetti. 
Questo *č* un memory leak perché non vengono rilasciate risorse delle 
quali io non ho piů bisogno e che non verranno mai piů usate. Perň solo 
alla terminazione del processo verranno recuperate (dal SO non dal GC).


 meno che la relativa classe non abbia un bug proprio in questo aspetto.
E se io non voglio piů usare l'oggetto riferito da window?


 alla terminazione del processo verranno recuperate (dal SO non dal GC).
Fammi capire, tu mi stai dicendo che se tutta la mia applicazione consiste 
nella sola main allora gli oggetti che si avvicendano non escono di scope fino 
al termine dell'applicazione? Questo mi sembra più che normale e, come ho già 
detto, non vedo come potrebbe essere diversamente. E continua a *non* essere 
memory leak in quanto non è affatto detto che io non abbia bisogno più tardi 
dell'oggetto in questione. Ripeto: come potrebbe essere diversamente? Io non 
riesco a considerare una cosa del genere come un difetto del GC.


 E in ogni caso questa non si chiama memory leak ma un bug del GC.
Se dopo 15-20 minuti di uso di un'applicazione questa arriva ad avere
allocato 300-400 MB di RAM poco importa se alla sua terminazione il
GC od il SO recuperano questa memoria, sta di fatto che io sono
costretto a terminare l'applicazione perché diventata inutilizzabile.


 E se io non voglio piů usare l'oggetto riferito da window?
Allora avresti dovuto creare un secondo scope. La presenza di un GC non ti 
autorizza a buttare alle ortiche tutti i buoni criteri dell'informatica.


 costretto a terminare l'applicazione perché diventata inutilizzabile.
Allora c'è veramente una memory leak ma non dipende dalla presenza o meno di 
un GC bensì da un bug da qualche parte (nel tuo codice, nelle librerie del 
linguaggio, nel GC stesso, ...).


 io non abbia bisogno più tardi dell'oggetto in questione. 
Invece *è* detto, te l'ho detto io. Io non ho più bisogno di
quell'oggetto. Il GC non può però saperlo a meno che io non ponga tutti i
riferimenti che lo riferiscono a null.


 Se il programma fosse composto da un'unico scope 
Unico scope? Non capisco cosa tu intenda per unico scope.
Se oggetto1 è un attributo di oggetto2, oggetto1 viene distrutto quando 
viene distrutto oggetto2. Se oggetto2 è un attributo di oggetto3,
oggetto2 viene distrutto quando viene distrutto oggetto3.
Quindi finché non viene distrutto oggetto3 non viene distrutto oggetto2
e pertanto neppure oggetto1. Non c'è nessun "unico scope", ma tutto
dipende da oggetto3 (e potrei continuare all'infinito). 
Se lo scope di oggetto3 è la main, oggetto3 non viene mai distrutto e
pertanto neppure oggetto2 ed oggetto1. Però io non ho più bisogno di
oggetto2 né di oggetto1 (perché non lo userò mai più). 
Solo ponendo a null tutti i riferimente ad oggetto1 e ad oggetto2 posso
far sì che il GC li distrugga, altrimenti rimarrano per sempre vivi
anche se assolutamente inutili.


 dell'oggetto) perché è necessario accedervi da più punti del codice.
Quindi vuoi dire che allochi risorse assegnandone il riferimento ad un 
attributo della classe, giusto? E perché ti aspetti che il GC sia in grado di 
rilasciare tali risorse? Quando dovrebbe farlo? Mi sfugge ancora qualcosa?


 anche se assolutamente inutili.
Ma una tale classe "finestra principale" siamo sicuri che sarebbe ben 
progettata? Certamente è molto diversa dalle classi analoghe che uso io che 
contengono esclusivamente ciò di cui hanno effettivamente bisogno e quindi non 
hanno alcunché da rilasciare. O meglio, lo fanno implicitamente, non devo 
preoccuparmene io, perché sono state progettate in modo da rispettare le 
proprie responsabilità.


 ci dimentica di rilasciare i riferimenti.
Mi sembra di capire che la situazione e' la seguente.
Un'applicazione che rimane a lungo in esecuzione (per esempio un server 
o un'applicazione grafica), in fase di inizializzazione, alloca un 
oggetto (per esempio il gestore di transazioni o la finestra 
principale), che rimane poi attivo per tutta la durata del processo.
A fronte di vari eventi (per esempio una richiesta di un client al 
server o un clic del mouse sulla finestra) un oggetto viene allocato e 
posto in una variabile membro dell'oggetto di cui sopra.
Alla fine della gestione dell'evento, il programmatore si deve ricordare 
di distruggere il riferimento a tale oggetto, altrimenti l'oggetto 
rimane in vita.
Secondo me questa e' cattiva programmazione, perche' ogni oggetto 
dovrebbe essere "posseduto" da una variabile dichiarata nello "scope" 
che ne descrive il ciclo di vita.
Un oggetto e' "posseduto" o "owned" da una variabile, quando tale 
variabile ha il compito di distruggere tale oggetto quando esce di scope.
Siccome ad ogni gestore di evento dovrebbe corrispondere uno scope, 
cioe' una porzione di codice racchiusa tra graffe, le variabili che 
devono esistere solo per la durata della gestione dell'evento, devono 
essere possedute da variabili contenute all'interno di tale scope, in 
modo che l'uscita dallo scope ne assicura la distruzione.
Se la variabile serve ad altre routine, dovra' essere passata loro come 
parametro.
Se le variabili da passare come parametro risultano troppe, si dovrebbe 
creare un oggetto che incapsuli tale stato temporaneo e passare tale 
oggetto per riferimento.
Se non si fa in questo modo, si rischia di cadere nella situazione 
caotica che si ha quando si usano solo variabili globali.


 linguaggio, nel GC stesso, ...).
L'applicazione è in Java e dubito ci siano tali bug nelle librerie del
linguaggio o nel suo GC.
L'applicazione non è mia e viene venduta per quasi 3000 ¤ nella sua
versione commerciale più completa.
Il bug è sicuramente nell'applicazione ed è dovuto, come sto dicendo da
20 post :) al fatto che il programmatore crede che il GC lo sollevi
dalla gestione della menoria, ma così non è. Anche in presenza di un GC
si è costretti a gestire manualemte la memoria, non facendo delle
delete, ma ponendo i riferimenti ad oggetti non più in uso a null.


 proprie responsabilità.
Ma anche questa contiene esclusivamente ciò di cui ha bisogno. Non ci
sono creazioni superflue di oggetti, ma oggetti che sopravvivono alla
loro utilità. Come ti ho detto in qualche post un oggetto "finestra
impostazioni" è necessario alla finestra principale, ma non per questo
deve rimanere vivo per tutta la durata dell'applicazione.


 delete, ma ponendo i riferimenti ad oggetti non piů in uso a null.
Sě, ma torno a dire che sono situazioni molto rare, almeno nella mia 
esperienza (ma io non uso Java).


 il ciclo di vita.
Proprio quello che dicevo anch'io.


 deve rimanere vivo per tutta la durata dell'applicazione.
E perché questa "finestra impostazioni" non dovrebbe vivere su di uno scope 
separato?


 rilasciare tali risorse? Quando dovrebbe farlo? Mi sfugge ancora qualcosa?
Se hai bisogno di accedervi da più punti del codice non vedo alternative. 
Ma non per questo devi far sì che rimangano allocate per il resto della
vita del processo.


 vita del processo.
Vediamo se ho capito. Faccio un esempio concreto (piattaforma Windows): la 
classe finestra principale ha un attributo Font. Creo un font (CreateFont()) e 
lo assegno a quell'attributo. Successivamente voglio cambiare il font della 
finestra e quindi distruggo il font precedente (DeleteObject()) e ne creo uno 
nuovo (CreateFont()). In tutto questo discorso il GC non c'entra proprio 
niente. Se il programmatore dimentica di rilasciare il font precendente 
(DeleteObject()) ci sarà indubbiamente memory leak ma non sarà colpa del GC.
Ho detto bene?


 caotica che si ha quando si usano solo variabili globali.
Molto spesso non è possibile per quanto detto sopra, non è il
programmatore a decidere quale sia il ciclo di vita degli oggetti.


 esperienza (ma io non uso Java).
Ti assicuro che non sono affatto rare. Nelle applicazioni con
interfaccia grafica questo è un problema comune.


 Proprio quello che dicevo anch'io.
Il problema è che il programmatore non può decidere lo scope degli
oggetti in certi tipi di applicazioni.


 riferimento in un attributo.
A me sembra che tu stia confondendo due aspetti diversi. Il lifetime dal punto 
di vista dell'utente e/o del sistema operativo non è necessariamente 
coincidente con lo scope della variabile che contiene il riferimento 
all'oggetto. Potrei farti un esempio reale ma dovrei utilizzare un linguaggio 
diverso dal C++ e non so se è il caso...


 separato?
Perché è l'utente a decidere quando la finestra viene chiusa, non il
programmatore.
Ora il caso della finestra impostazioni non è corretto in tal senso in
quanto è una finestra modale, ma pensa alla vista di un documento in
un'applicazione che permetta più documenti aperti contemporaneamente.
Chi è che decide il ciclo di vita dell'oggetto che rappresenta la viste
del documento? Il programmaotore? No. È l'utente dell'applicazione.


 diverso dal C++ e non so se č il caso...
Sě se c'č il GC, perché questo distrugge tutti gli oggetti che non sono
piů raggiungibili.
Puň essere che qualche linguaggio funzioni in modo diverso, ma
sinceramente mi pare piuttosto strano.


 interfaccia grafica questo è un problema comune.
Allora è un problema che a me è sempre sfuggito. :-) Strano che abbia 
applicazioni che girano ore ed ore senza problemi di memory leak... :-)


 oggetti in certi tipi di applicazioni.
Non so. Finora purtroppo non mi hai fatto capire quali. Gli esempi che mi hai 
fatto (finestra non modale) non hanno i problemi da te lamentati nei linguaggi 
che uso io. Che ti devo dire?


 che uso io. Che ti devo dire?
Io non voglio mettere in dubbio la tua bravura, ma sei sicuro di non
avere memory leak? Un processo che usa 5 MB di memoria incece che 1 a
causa di memory leak non dà alcun problema e nessuno se ne accorge.


 considerato piů facile rispetto a linguaggi come il C e il C++?
Marketing.


 anche se assolutamente inutili.
1. se tu hai una classe con dei membri che a un certo punto sai di
potere buttare via, avrai dei metodi per farlo. Altrimenti è un errore
di design.
2. La situazione da te presentata (a meno che io non abbia capito bene)
si presenta anche in C++
class A{
   B b;
   // etc
};
class B{
   C c;
   // etc
public:
   B() :c() {};
}
class C;
int main(){
    A a();
    a.createB(param);
    main_loop(a);
}
ovviament finchè non esco da main, A non viene deallocato. E lo stesso
vale per B e per C. Se li voglio deallocare, farò un 
a.setB(null);
con GC
e senza farò
a.deleteB();
non capisco...
-- 
Python è un linguaggio specialistico nel senso che è specializzato 
nel fare fare le cose rapidamente e bene.

 std::tr1::shared_ptr) che gestiscono il problema della concorrenza.
Molte delle aggiunte proposte "ci sono già". Voglione essere incluse
nello standard, tutto qui.


 del documento? Il programmaotore? No. È l'utente dell'applicazione.
Aspetta: tu crei una finestra non modale e ne assegni il riferimento ad una 
variabile. Successivamente l'utente chiude la finestra non modale ma il 
riferimento è ancora assegnato alla variabile di cui sopra. Quindi la finestra 
è rilasciata per quanto concerne il sistema operativo (e quindi le sue risorse 
sono già state correttamente deallocate) ma il riferimento all'oggetto ormai 
non valido è ancora legato alla variabile di cui sopra e quindi non viene 
restituito al GC. Ma nel momento in cui crei una nuova finestra modale e ne 
assegni il riferimento alla stessa variabile, l'oggetto precedente perde ogni 
riferimento e quindi può venire restituito al GC. Ecco che, per i due motivi 
di cui sopra (rilascio da parte del sistema operativo e sostituzione degli 
oggetti nell'unica variabile), il problema è molto meno grave di quello che 
sembra, praticamente trascurabile.


 causa di memory leak non dà alcun problema e nessuno se ne accorge.
No, aspetta: una memory leak è progressiva. L'uso di risorse superiore al 
previsto ma comunque in quantità costante non vedo come possa essere una 
memory leak.


 Marketing.
Be', no, direi di no. E' *obiettivamente* più facile, tanto è vero che ci sono 
schiere di (cattivi) programmatori in linguaggi con GC e relativamente pochi 
(cattivi) programmatori C/C++. Questo perché per un cattivo programmatore è 
molto più semplice riuscire a realizzare qualcosa di bene o male funzionante 
quando è il GC ad occuparsi della gestione della memoria, fidati.


 Nel caso dovresti provare a fornirmi dei numeri, se li hai.
Poseidon, Eclipse, NetBeans, SunStudio, ecc... Tutte le applicazioni di
un certo "spessore" soffrono di questi problemi. Sarà un caso?


 non capisco...
Appunto... Non c'è nessuna differenza fra l'avere il GC e il non averlo.
E allora che ci sta a fare?


 venire restituito al GC. 
In questo caso sì, ma tieni presente che riassegnare alla stessa
variabile significa che sai con certezza che l'utente ha chiuso la
finestra, inoltre non è possibile avere più di una finestra di quel
tipo aperta, cosa che molto facilmente potrebbe non essere.


 E allora che ci sta a fare?
Per me quello è un caso rarissimo. Anzi, non mi pare ci sia mai nelle mie 
applicazioni. In tutte le altre situazioni avere un GC è comodo e *riduce* le 
possibilità di errore.


 memory leak.
Il non rilascio di memoria precedentemente allocata e non più usata è un
memory leak, anche se non è progressivo (spesso lo è ma non sempre).
Può dipendere anche da come viene usata l'applicazione.


 tipo aperta, cosa che molto facilmente potrebbe non essere.
A meno che gli attributi non vengano aggiunti alla classe in runtime (cosa 
possibile in alcuni linguaggi) è ovvio che si parlava di uno o comunque un 
numero fisso di attributi.


 quando è il GC ad occuparsi della gestione della memoria, fidati.
Non dipende dalla presenza del GC, dipende dalla complessità del
linguaggio.


 Può dipendere anche da come viene usata l'applicazione.
Anche se l'esecuzione passasse una sola volta attraverso la parte di codice 
che presenta memory leak, sarebbe sempre progressivo, almeno per come la 
intendo io.


 linguaggio.
Sì, ma in generale la complessità del linguaggio è ridotta dalla presenza del 
GC.


 numero fisso di attributi.
Ho scritto talmente tanti post che non mi ricordo più quando ho scritto
qualcosa ed in risposta a chi, ma sono a casa con l'influenza e non
posso uscire :(
Editor che permette di avere più documenti aperti.
Click sul pulsante nuovo documento o apri documento
Viene aperta (in un qualche modo) una vista del documento.
L'oggetto che rappresenta questa vista deve chiaramente sopravvivere
alla routine crea/apriDocumento, deve essere necessariamente accessibile
a più parti del codice pertanto è necessario memorizzarne un riferimento
come attributo dell'oggetto finestra principale.
Posso creare (virtualmente) un numero infinito di queste viste, quindi
userò una qualche contenitore apposito (un vector, una map, ecc..).
Non conosco il ciclo di vita di questi oggetti (è l'utente che decide
quando chiudere queste viste).
Quando l'utente chiude la finestra nell'evento di chiusura devo
necessariamente porre il riferimento a null (o rimuoverlo dal
contenitore) altrimenti non l'oggetto non può venire distrutto dal GC.
Se mi dimentico di farlo e l'utente apre poche di queste viste non me ne
accorgo.
Se l'utente continua ad apreire e chiudere viste di documenti il leak
diviene evidente in breve tempo.


 GC.
Per te il C++ sarebbe meno complesso con un GC (anche ammettendo di non
doversi mai occupare di riferimenti da porre a null, ecc..)?


 un certo "spessore" soffrono di questi problemi. Sarà un caso?
Tutte con GUI. Sarà un caso?


 E allora che ci sta a fare?
Perchè quello è il codice che hai proposto tu. E che peraltro non
presenta il problema che tu paventavi.


 del GC.
Questo dicono i vari studiosi che si occupano di produttività. 
Io nonostante scriva molto più codice C++ che altro in Python sono circa
5 volte più produttivo, in ObjectiveC circa il triplo e Java non so,
sono molto meno skillato. Se in un ambito che conosco circa il doppio.
I numeri sono dati molto a spanne e ovviamente contano "righe di codice
debuggate e con test di base scritti (alla JUnit)".
A proposito, qualcuno ha da consigliarmi una buona libreria di test per
C++?


 Tutte con GUI. Sarà un caso?
No, non lo è affatto, e l'ho detto io stesso più volte e non ho spiegato
più o meno anche i motivi (l'impossibilità per il programmatore di
gestore il ciclo di vita degli oggetti).


 sono molto meno skillato. Se in un ambito che conosco circa il doppio.
ObjectiveC non lo conosco affatto ma Python e Java hanno una libreria 
pressoché totale, è pertanto ovvio essere più produttivi (qualunque cosa 
questa parola voglia dire) che in C++ la libreria standard del quale è
estremamente limitata ed occorre scriversi tutto a mano od andarsi a
cercare varie librerie in giro (magari con "stili" di programmazione ed
uso diversi tra loro).
Questa è sicuramente una pecca del linguaggio, nessuno lo mette in
dubbio (sperando che lo standard introduca un bel po' di novità -a
livello di libreria-), ma non ha nulla a che fare con la presenza del
GC.


 diviene evidente in breve tempo.
Sì, ho capito ma a me personalmente non verrebbe mai in mente (e penso che non 
verrebbe in mente a nessun programmatore degno di questo nome) che un oggetto 
che io ho inserito dentro un contenitore mi venga poi rilasciato 
automagicamente da un qualsivoglia GC.


 doversi mai occupare di riferimenti da porre a null, ecc..)?
Sì, se il C++ fosse stato progettato con il GC in mente. Non credo che il 
semplice innesto di un GC in un linguaggio precedentemente privo di GC possa 
renderne meno complesse le funzionalità preesistenti. Forse quelle sviluppate 
in seguito.


 gestore il ciclo di vita degli oggetti).
O semplicemente librerie di GUI un po' tanto buggate. Ad ogni modo qui
prendono molte risorse, ma *non* leakano (non in modo percepibile).


 GC.
In effetti si. In Python scrivo codice con la certezza che il sistema si
preoccupa per me di alcune cose (fra cui la gestione della memoria). E
il gc si fa sentire.


 automagicamente da un qualsivoglia GC.
Non ho una visione altrettanto ottimistica.


 Sě, se il C++ fosse stato progettato con il GC in mente.
Se fosse stato progettato per essere Java sarebbe Java :)
Quante delle caratteristiche del C++ che lo rendono complesso dipendono
dalla gestione manuale della memoria?


 (non in modo percepibile).
Uhm... fatico a vedere 300-400 MB come "prendere molte risorse".
In ogni caso SWT č invece piuttosto parca nel consumo di memoria in
quanto č stata progettata in modo completamente diverso da Swing, 
eppure anche Eclipse non scherza.


 eppure anche Eclipse non scherza.
Qui Eclipse di memoria reale prende 170 MB. E sul MacOS le GUI Java sono
qualcosa di disastroso.


 dalla gestione manuale della memoria?
Probabilmente le stesse che rendono complesso il C.


 qualcosa di disastroso.
SWT č concepita in modo completamente diverso da Swing.
Swing emula tutti i widget, SWT usa quelli nativi, per cui le GUI
scritte con SWT sono integrate con il SO, molto piů reattive e parche
nel consumo di memoria, e cos' dovrebbe essere anche su MacOs.
Ma non si sfugge comunque a Java...


 Probabilmente le stesse che rendono complesso il C.
Da quando il C è considerato un linguaggio complesso?
Si usa persino com elinguaggio per imparare a programmare...


 
io uso cxxtest (
http://cxxtest.sourceforge.net/
)
-- 
"E' solo dopo aver perso tutto che siamo liberi di fare qualsiasi cosa."

 Ma non si sfugge comunque a Java...
Vero. Java succhia molta RAM di suo. 


 io uso cxxtest (
http://cxxtest.sourceforge.net/
)
TY.


 di forza del C++.
Smart pointer e garbage collection non sono la stessa cosa. In ogni
caso nessuno vuole introdurre un meccanismo di GC obbligatorio in C++.
Semplicemente si vuole aggiustare la semantica di base del linguaggio
per garantire di poter implementare *a livello di libreria* garbage
collector efficaci.
Ciao,
Nicola

 Eclipse e Poseidon.
Io l'ho sempre detto che scrivere applicazioni GUI di uso continuativo
in Java e' una fesseria...
Ciao,
Nicola

 applicazioni di una certa dimensione).
Intanto non e' nella filosofia del C++ impedire al programmatore di
farsi del male da solo e questo e' solo un altro modo. Si potrebbe poi
obiettare che impedire l'accesso a memoria non valida e' piu'
importante che non limitare lo spreco della memoria, anche se sono io
il primo a considerare discutibile quest'argomentazione: il software
funziona se e' fatto bene, non perche' i disastri non sono visibili.
Per contro la garbage collection consente l'implementazione di stili di
programmazione che attualmente il C++ supporta poco e male; penso in
particolare a closure e currying, indispensabili per un'implementazione
seria della programmazione funzionale.
Ciao,
Nicola

 come array di wchar_t. Meglio a questo punto un tipo apposta, no?
Sono abbastanza d'accordo, anche se penso ci siano alcune distinzioni
da fare. Il primo problema e' come e' memorizzata la stringa. Il C++
assume che le stringhe da usare internamente siano sempre fatte di
caratteri di dimensioni costanti e non so se questa e' una scelta
ragionevole. Pero' trovo che il fatto che alcuni algoritmi di uso
tipico con le stringhe non siano implementabili con una visione
carattere per carattere come lo sono nella libreria standard C sia un
problema, certamente serio, ma slegato dal precedente. Penso ad esempio
alla conversione maiuscolo-minuscolo e viceversa, che in alcuni casi
non mantengono il numero di caratteri (o il numero di caratteri non
coincide col numero di glifi).
Ciao,
Nicola

     
http://digilander.libero.it/carlmila
 

 Si usa persino com elinguaggio per imparare a programmare...
Il C non è adatto come primo linguaggio. Il C++ ha cercato (con risultati 
forse non perfetti) di alzare il livello del C proprio per ridurne la 
difficoltà.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 difficoltà.
IMHO riuscendo invece a complicarlo notevolmente. Aumenta la comodità di
lavorarci semmai, ma questo è diversa dalla semplicità (e specie di
quella di apprendimento).
-- 
L'idiozia trascende il mezzo con cui viene espressa.

 seria della programmazione funzionale.
Mi pare voler metter troppa carne al fuoco. Il C++ è un linguaggio che
ha uno dei suoi punti di forza nell'essere multiparadigma, ma mi pare
pericoloso volerlo estendere troppo.
Ciao.
-- 
BSD is for UNIX lovers -- linux is for Windows haters.

 inoltre ognitanto impazzisce (credo che lo faccia solo su Mac) e
No, impazzisce sotto qualunque SO.


 difficoltà.
Il C non è difficile. È difficile (se non impossibile) programmare in C
senza fare errori, ma sono due cose completamente diverse.


 livello di libreria* garbage collector efficaci.
A me pare che già ora ci siano librerie molto efficaci in questo.


 senza fare errori, ma sono due cose completamente diverse.
Deduco che non hai mai provato ad insegnare il C come primo linguaggio...


 pericoloso volerlo estendere troppo.
Ti consiglio di leggere qualcosa a proposito dei Domain Specific
Languages.
Ciao,
Nicola