Newsgroup: it.comp.lang.c++
Titolo: Tempi di compilazione... Non si può continuare così!!!

Per compilare il mio progetto di 30.000 linee di codice, il compilatore
(ottimizzando il tutto!) ne compila più di 10 Milioni (tutte dovute ai .H)
facendomi aspettare più di 1 ora (con un Pentium II 266!).
Con altri linguaggi, se si hanno progetti da 30.000 linee di codice, il
compilatore ne compila 30.000!
Non sarebbe meglio che si facesse una piccola modifica al linguaggio C++ per
rendere le compilazioni meno gravose?
In Java credo che questo problema non esista!
Una domanda precisa:
Quale pensate dovrebbe essere il tempo perso per ogni compilazione per non
incidere gravemente sul rendimento lavorativo?
Spero che al più presto le CPU corrano a 200 GHz (fatemela sparare!!) in
modo che i tempi di compilazione si riducano a tempi accettabili!
e poi c'e' anche chi dice che adesso le CPU sono molto più veloce di quanto
serve!! GRRRRR!!!!!!!
Grazie a chi vorrà intervenire.
--
Alessandro Pulvirenti
ale...@cedss.it

 wrote in message
news:7345ea$g8d$1...@fe2.cs.interbusiness.it...

Io ho un K6-2 3dNow 300, quindi suppongo che sia peggiore del tuo, ma
compilo progetti anche più grandi, in pochi minuti. Cosa usi esattamente? Se
VC++, sei sicuro di utilizzare:
1) Gli header precompilati
2) La compilazione incrementale
3) Il link incrementale
4) Un hard disk per l'output e non un floppy [ ;-) ]
5) Una quantità di RAM adeguata (64M sotto 95/98, 128 sotto NT)
?
Con gli header precompilati ed un buon makefile, mi sembrano tempi
inaccettabili.
Ciao.

inaccettabili.
Utilizzo il Borland C++ Builder 3.0 per compilare un progetto contenente:
100 Form per l'interfaccia grafica
120 files cpp che contengono il motore del programma
Utilizzo tutte le opzioni che hai accennato tu! ma quando vai a modificare
un file .H che contiene una classe base che è vista da tutto il progetto, il
progetto viene completamente ricompilato.
Impiega più di un ora per fare il "Build All" (compilazione totale!)
Specifico meglio il PC che utilizzo:
Pentium II 266Mhz
256 MB di RAM
2 Hard Disk (6 GB e 2 GB) Ultra DMA
in più... sfrutto entrambi gli Hard Disk in modo che un HD non sia
sovraccaricato di lavoro mentre l'altro sta fermo!
Quando i progetti si fanno un pò più complessi dei soliti banali programmini
con quattro finestre... i tempi di compilazione salgono esponenzialmente!
Ringrazio chi, avendo sviluppato progetti di grandi dimensioni, interverrà
raccontando come ha fatto a evitare che i tempi di compilazione dei computer
diventassero insostenibili.
Ricordo che c'era un articolo che diceva che quando la Microsoft doveva
ricompilare tutti i files di Windows per generare il sistema operativo,
c'erano una ventina di computer che compilavano per una decina di ore!!
Voi ne sapete qualcosa?
--
Alessandro Pulvirenti
ale...@cedss.it

progetto viene completamente ricompilato.
Evidentemente ci sono molte dipendenze tra i file.
Devi cercare di isolare i file header stabili da quelli soggetti a modifiche,
usa gli header precompilati limitandoti ai soli file stabili, in questo modo
diminuisci la possibilita` di una massiccia ricompilazione.
usa questa tecnica per includere un file:
#ifndef FLAG_FILE_HEADER
  #include <file.h>
#endif.
In questo modo eviti che il file .h ria riaperto e riprocessato se l'operazione e`
gia` stata eseguita in precedenza.
Cerca di limitare l'inclusione di file header dentro altri file header (in alcuni casi e`
possibile) in questo modo diminuisci la dipendenza tra header facilitandone
la stabilita`.
Paolo
-----------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
  e-mail: 
mar...@cli.di.unipi.it
 
-----------------------------------------------

Paolo
Sfortunatamente le dipendenze tra i files sono già al minimo!!
Si è creato una specie di albero a molti livelli e quando modifico i files
.H del livello più basso, tutti quelli dei livelli più alti vengono
ricompilati.
Comunque grazie!
--
Alessandro Pulvirenti
ale...@cedss.it


ale...@cedss.it
Ho notato che il Visual C++ in questo (attenzione, è una rarità) è migliore
del Borland! Almeno, dalla versione 5 in poi, se fai una modifica *poco
rilevante* ad un header file, i sorgenti da questo dipendenti non vengono
ricompilati. Quante volte capita di aggiungere o eliminare un commento,
oppure aggiustare semplicemente l'indentazione, oppure ancora aggiungere un
parametro ad un metodo che la maggior parte dei sorgenti non utilizza; il
visual C++ è in grado di discernere questi casi, dalle modifiche più serie,
in cui una compilazione è necessaria.
Venendo alla Microsoft, mi raccontava qualcuno di essere entrato in un
laboratorio che loro usano per le compilazioni; ci sono un bel po' di server
in grado di compilare in parallelo; hanno lanciato la ricompilazione totale
del Microsoft Jet Engine, e c'è voluta mezza giornata. Figuriamoci tutto
Windows 98!
Ciao.

Ciao.
Questo mi consola... non sono l'unico che ha problemi di compilazione!
Il Windows di cui parlavo io era la vers. 3.1 a 16 bit.
Penso che per Windows 98 avranno qualche problemino in più... compileranno
nelle ferie!!
Ciao
--
Alessandro Pulvirenti
ale...@cedss.it

diventassero insostenibili.
Temo che, senza una "ri-fattorizzazione" del tuo progetto
che puo` probabilmente richiedere uno sforzo eccessivo,
il problema non si risolva; _diminuira`_, col passar del
tempo, se ed in quanto si "stabilizzano" i sottosistemi dai
quali si hanno piu` dipendenze.
Scagli la prima pietra chi, al suo primo progetto C++ di
dimensione appena appena rilevante (qualche decina di
migliaia di righe, mica nulla di enorme), non e`
incappato in un problema di "classe base fragile" o
altra dipendenza fuori controllo...!-(
Se uno e` veramente fortunato, ha la chance di
"rifattorizzare" -- esaminare le dipendenze, e rifare
l'intero progetto in modo di non avere mai:
    A -> B (A dipende da B)
dove A e` un componente (sottosistema) piu`
stabile di B.  Robert Martin e` probabilmente
l'autore che ha scritto le cose piu` interessanti
su queste "ri-fattorizzazioni", e in particolare
a lui e` dovuto il "principio di inversione della
dipendenza", che riassumo: quando l'analisi
mostra una "mala dipendenza" (componente
piu` stabile che dipende da componente meno
stabile), "invertire la dipendenza" introducendo
interfacce astratte, nuovo componente C:
    A -> C    A _usa_ le interfacce C
    B -> C    B _implementa_ le interfacce C
Le interfacce astratte, che "specificano" un set
di funzionalita` ma non le _implementano_,
possono piu` agevolmente essere stabilizzate,
rispetto alle implementazioni.
Fra le tecniche di progetto che, se applicate
sin dall'inizio, possono evitare l'insorgere del
problema degli eccessivi accoppiamenti fra
componenti, le interfacce astratte giocano pure
un ruolo fondamentale.  Alcuni autori, come
Meyers, arrivano a raccomandare di non
usare MAI l'eredita` fra classi concrete --
approccio forse un po' troppo estremistico,
ma da prendere in considerazione, almeno
come "linea-guida".  Se non altro, si puo`
[a] delineare una partizione del progetto in
termini di _componenti_ (o sottosistemi che
dir si voglia), [b] porre cura all'analisi delle
dipendenze fra componenti, e [c] in special
modo, esaminare criticamente qualsiasi caso
in cui si sia tentati di usare eredita` da classi
concrete "attraverso" il confine fra due
diversi componenti.
C'e` dell'altro, naturalmente, ma queste sono
le prime considerazioni che vengono in mente...
Alex

>ricompilati. Quante volte capita di aggiungere o eliminare un commento,
Io sto lavorando ad un gestionale da parecchi mesi e oramai per compilare
l'intero progetto ci impego ore.
Ti consiglio di suddivere il progetto in due parti, la prima è composta dal
nucleo del programma e la compili come una libreria. Successivamente ogni
parte del progetto a se' stante viene suddivisa in piu' progetti separati.
Ognuno di questi progetti diventa una dll che al suo interno include la
libreria ...
In questo modo ottieni:
1) Ogni parte è separata e quando la modifichi non serve ricompilare il
resto
2) Se piu' persone lavorano al progetto, si riducono errori e problemi di
condivisione
3) Ricompilando il nucleo, ha la necessità di ricompilare tutto solo quando
fai delle modifiche "importanti", ad esempio aggiungendo variabili /
funzioni ad una classe o cambiano costanti (solo per le dll che usano quelle
costanti ), ecc. (in pratica e' quello che fa il VC++ 5 in modo automatico,
e te lo assicuro non lo fa mica tanto bene)
Con questa modalità (e con altri piccoli accorgimenti) ti assciuro che eviti
veramente un sacco di ricompilazioni.
Ciao.

delle dipendenze vi figura, giustamente, nel ruolo dominante.
Mi puoi fornire il nome della casa editrice, titolo del libro e dove poterlo
comprare?
Tutti i libri che trattano tale argomento sono per me importantissimi!!!
me ne puoi elencare qualcuno (se possibile in italiano).
Grazie
--
Alessandro Pulvirenti
ale...@cedss.it

me ne puoi elencare qualcuno (se possibile in italiano).
In Italiano mi viene in mente solo Carlo Pescio, "C++
manuale di stile", e non conosco la casa editrice; ma
e` testo assai scarno e introduttivo rispetto al Lakos,
ed altri similmente "messi a fuoco".
In inglese, sul tema "gestione delle dipendenze in
C++" aggiungerei (sempre da 
www.amazon.com
):
Designing Object-Oriented C++ Applications : Using the Booch Method 
by Robert Cecil Martin 
 
Our Price: $53.00
Availability: This title usually ships within 24 hours.
Hardcover - 528 pages (March 1995) 
Prentice Hall; ISBN: 0132038374 ; 
Dimensions (in inches): 1.10 x 9.61 x 7.23 
Sul tema "progettazione a oggetti con uso delle
classi astratte":
Design Patterns : Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing) 
by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 
Our Price: $49.95
Availability: This title usually ships within 24 hours.
Hardcover - 395 pages 2400 edition (October 1994) 
Addison-Wesley Pub Co; ISBN: 0201633612 ; Dimensions (in inches): 1.34 x 9.59 x 7.68 
E sul tema "uso efficace del C++" (compresi, fra
tanti altri argomenti, anche parecchi di diretto
impatto sulla questione da te sollevata):
Effective C++ : 50 Specific Ways to Improve Your Programs and Designs (Addison-Wesley Professional Computing Series) 
by Scott D. Meyers 
Our Price: $39.95
Availability: This title usually ships within 24 hours.
Paperback - 256 pages 2nd edition (September 1997) 
Addison-Wesley Pub Co; ISBN: 0201924889 ; Dimensions (in inches): 0.57 x 9.18 x 7.39 
More Effective C++ : 35 New Ways to Improve Your Programs and Designs (Addison-Wesley Professional Computing Series) 
by Scott Meyers 
 
Our Price: $39.95
Availability: This title usually ships within 24 hours.
Paperback - 318 pages (December 1995) 
Addison-Wesley Pub Co; ISBN: 020163371X ; Dimensions (in inches): 0.92 x 9.16 x 7.33 
Cinque stelle anche al Martin, quattro e mezzo a ciascuno
degli altri tre (secondo me sono tutti da cinque stelle).
Del "More Effective C++" e` probabile che esca una 2a edizione
aggiornata fra non piu` di un 6 mesi circa, ma anche il testo
del '95 e` secondo me validissimo.
Alex

veramente un sacco di ricompilazioni.
Il programma è suddiviso in 10 moduli, pensi che sia il caso di suddividerlo
ancora ?!
Grazie per il consiglio, ma queste cose l'ho già applicate.
Di compilazioni lunghe in questo periodo non ne faccio più di una max due al
giorno, mentre le altre sono molto ridotte (max 10').
Comunque mi hanno dato un suggerimento anche come potenziare il PC e a
Gennaio metterò 2 Pentium II a 400 MHz in parallelo con Windows NT 4.0.
Addio Windows 98!


Questo non evita le ricompilazioni vere!
Questo mi ricorda una tecnica che forse gia` conoscerai,
ma forse invece potrebbe farti comodo -- denominata da
Herb Sutter "Fast Pimple".
L'idea base, il "Pimple", e` questa: ereditare da classi
concrete e` un disastro, in termini di controllo delle
dipendenze, come e` chiaro a tutti quelli che hanno un
po' di prassi reale di programmazione OO ("gli altri"
si distinguono per affermazioni veramente egregie,
come il dubitare che limitare l'eredita` a classi astratte
sia "vero polimorfismo nel senso dell'OO" -- lo so,
sembra incredibile, ma si e` vista questa asserzione
sui gruppi it.comp.* questo stesso autunno!!!).
Ma se un progetto e` stato, ahime`, impostato in termini
di "classi concrete", come ristrutturarlo senza riscriverlo
da capo, sostituendo tutte le istanze concrete (quelle che
danno problemi di mala dipendenza, almeno) con puntatori
ad istanze astratte, "classi-fabbrica", ecc ecc?  L'eccellente
idioma "inversione delle dipendenze" di Martin NON impedisce,
sigh, di riscrivere valanghe di codice...:-(.
Supponiamo che inizialmente tutto fosse impostato su
di una classe base concreta, poi dimostratasi fragile,
"class B": per cui ho un tot di "class D: public B",
variabili locali di tipo B, ecc ecc.  Adesso ho applicato
la "inversione di dipendenza", per cui ho una classe
astratta A che cattura il carattere astratto di cio` che
B deve fare, "class B: public A" limitata ad implementare
questo "carattere astratto", e gli opportuni metodi
fabbrica (magari fabbriche astratte, cfr Gamma, et
al, "Design Patterns", Addison-Wesley) che ritornano
degli A* (o magari auto_ptr<A>, ecc).  Ma come faccio
a togliere le dipendenze dalla classe concreta B, la cui
implementazione si dimostra cangiante, da tutti i
sottosistemi "piu` stabili" ("di piu` alto livello"), senza
dovere riscrivere tutto...?!
L'idioma Pimple aiuta proprio in questa transizione.
Cambia nome alla classe concreta che implementa A,
es "class BA: public A" eccetera.  Fai una nuova classe
concreta B che non e` che un _guscio_ (magari via uno
smart pointer reference counted, magari via un
auto_ptr<>, dipende!) verso le funzionalita` di A:
    class B: public A {
        A* pImpl;
    public:
        B();     // se un default ctor ha senso
        B(int); // ev. altri costruttori
        ~B();   // e distruttori
        // poi tutti i metodi, delegati, spesso
        // in-linea:
        int met1() const { return pImpl->met1(); }
        void me2(int* pI) { return pImpl->me2(pI); } // v. nota
        // ecc ecc
    };
nota: il C++ Standard ammette "return espressione;",
dove espressione e` void, in una funzione void, proprio
per rendere di un epsilon piu` comodo l'importante
idioma pImpl, soprattutto quando espresso in template;
probabilmente il vostro compilatore preferito non sa
ancora implementare questa particolarita`, per cui nei
casi di metodi void dovrete omettere il "return"!
Dovrebbe essere chiaro, a questo punto, che "pImpl"
significa "pointer to Implementation", e viene detto
scherzosamente "pimple" ("foruncolo") piu` che altro
per il valore mnemonico.  Grazie ai metodi inline, il
metodo puo` essere reso _quasi_ privo di costi a
run time... da B si puo` ereditare, come prima che
adottasse l'idioma pImpl -- si puo` dichiarare delle
variabili locali di tipo B, passarlo per valore, ecc ecc;
il "costo" e` in sostanza la tipica indirettezza (e una
chiamata virtuale) -- "un affare", considerando che,
se A e` stabile come un'interfaccia astratta dovrebbe
essere [penso che dovro` postare a parte qualche
dritta su come evitare il problema della "classe base
grassa", spesso confuso con quello della "classe base
fragile"...?  Ditemi un po' voi!], allora lo e` anche B
(puro, meccanico "passamano" al suo pImpl di tutte
le relative funzionalita`!).
Con UNA grande eccezione...!
Scritto cosi`, l'idioma pimple sembra implicare una
allocazione in heap (o "free store" che dir si voglia)
per ogni B istanziata; anche se P. Marotta pare, da
quanto asserisce nel suo piu` recente post al thread
"quali linguaggi di programmazione si insegnano a
scuola", non capire l'enorme differenza di costo di
runtime fra un'allocazione in heap e una in stack,
qualsiasi decente programmatore C++ ne e` invece
perfettamente cosciente -- egli sa, infatti, che e`
proprio dalla possibilita` che il C++ offre di avere
"oggetti qualsiasi" residenti _in stack_, che viene il
grosso del suo "vantaggio inerente di prestazioni"
rispetto a qualsiasi altro linguaggio OO esistente
(se non altro perche` qualsiasi decente programmatore
C++ ha letto il testo di Stroustrup, che spiega bene
come questa innovazione sia LA innovazione cruciale
di C++ rispetto a linguaggi OO preesistenti come
Simula!).
E quindi, detto "programmatore C decente" non e`
affatto contento della prospettiva che ciascuno dei
suoi oggetti di classe B, residenti in stack, si porti
dietro una implicita allocazione da heap (quella dove
risiede la "implementazione" cui pImpl punta)!  E`
mai possibile che per ridurre i tempi di compilazione
si debba pagare un rilevante scotto a run-time...?-(
Arriva al soccorso il cavaliere bianco Herb Sutter in
un suo "Guru of the Week" di quest'estate: no, _si
puo`_ evitare l'odioso "taglieggiamento"!-)  Herb,
in realta`, non fa altro che mettere insieme due idiomi
molto classici: "pimple", che egli ha il merito di avere
denominato ma di cui non pretende certo quello di
averlo _inventato_ (nell'87, quando di C++ ne avevo
capito ancora piuttosto poco, il pImpl in qualche forma
io gia` lo usavo...:-), e "fast-alloc", ``idioma'' che e`
talmente lungi dall'essere originale che C++ ha da
molti anni uno specifico costrutto solo per supportarlo!
Ma, come spesso succede, la sinergia fra cose note
produce qualcosa di nuovo e potente (cfr, per le
"compound pattern" in generale e un ottimo esempio
in particolare, la column di Vlissides sull'ultimo C++
Report).  Supponiamo che la classe che implementa
in pratica la interfaccia astratta "class A" sia qualcosa
come (in un file "privato"):
        class BA: public A {
            int* pInt;
        public:
            BA(int);
            // tanti altri dati e metodi
        };
e venga normalmente generata da una fabbrica
(invocata dai vari costruttori di B, ecc):
        A* makeA(int x) {
            return new BA(x);
        }
ebbene, per trasformarla in "fast pimple", basta
una minuscola modifica del tipo...:
        class BA: public A {
            union {
                int* pInt;
                BA* pNextFree;
            }
            static BA* freelist;
            void* operator new(size_t x) {
                void* result;
                if(t==sizeof(BA) && freelist) {
                    result = freelist;
                    freelist = freelist->pNextFree;
                } else {
                    result = ::operator new(x);
                }
                return result;
            }
            void operator delete(void* p, size_t x) {
                if(x!=sizeof(BA)) {
                    ::operator delete(p);
                } else {
                    BA* pB = reinterpret_cast<pB*>(p);
                    pB->pNextFree = freelist;
                    freelist  = pB;
                }
            }
        public:
            BA(int);
            // tanti altri dati e metodi
        };
        // nel file d'implementazione, ovviamente:
        BA* BA::freelist = 0;
Le cautele sull'argomento di tipo size_t diverso
da sizeof(BA) possono naturalmente venir omesse
se da BA non si deriva mai (o almeno non senza
ulteriori override degli operator new e delete).
Il punto e` che, con questo tipico idioma fast-alloc
in qualcuna delle sue ben note variazioni (che gli
operator new e delete per classe del C++ esistono
in sostanza proprio per supportare!), il costo
ammortizzato delle operazioni di allocazione e
liberazione di un oggetto di tipo "class BA" diventa
molto ridotto (c'e`, naturalmente, una ricca
letteratura sul tema degli allocatori a slice fissa,
che si puo` a volte fruttuosamente applicare al
posto della semplicissima "free-list" qui usata).
Applicando l'idioma fast-alloc all'idioma pimple,
si ha (chi l'avrebbe mai detto, eh?-) l'idioma
composito fast-pimple, che ci offre per certi
versi "il migliore dei mondi possibili".
Attenzione: come tutte le applicazioni, anche
questa e` meglio applicarla _a ragion veduta_,
NON "aprioristicamente"!  PRIMA misurare il
runtime della propria applicazione, allo scopo
di verificare che, con pimple ma senza fast
pimple, le operazioni di heap su oggetti di classe
BA comportano un overhead misurabile; POI, se
cosi` in effetti e`, ottimizzare (con un occhio di
riguardo alle prestazioni di memoria virtuale,
ovviamente, che sono generalmente determinante
numero uno delle prestazioni di allocazione di
qualsiasi grossa applicazione).  Penso di stare
parlando ad un "pubblico maturo", che non ha
davvero bisogno di questi avvertimenti, sapendo
infatti gia` come le intuizioni del programmatore
sulle prestazioni dei programmi siano notoriamente
ingannevoli, come frammentare la VM possa
comportare dei costi "nascosti" molto alti [dopo
tutto la VM c'e` da 30 anni, ormai si puo` sperare
che le tecniche basilari che la riguardano le abbiano
capite tutti, si?-)], ecc ecc; mi limito quindi ad
offrire un suggerimento da prendere nella dovuta
considerazione se interessa controllare le dipendenze,
gestire elegantemente la migrazione dall'uso di classi
concrete a quello di classi astratte, e allo stesso
tempo tenere sotto controllo i costi di runtime!-)
Alex

runtime fra un'allocazione in heap e una in stack,
La sua capacita` di estrapolare da frasi significati ben lontani da quelli
reali non finira` mai di stupirmi, come ad esempio l'asserzione "pare, da quanto
asserisce....non capire...". Dove mai ho asserito o solo insinuato qualcosa di simile?
Mi sembra che nel post in questione si parlasse (non si capisce molto, perche` per dimostrare
la generalita` di una sua tesi, tende sempre a portare esempi molto specifici, e comunque
non inoppugnabili) di gestione di errori, argomento tirato in ballo per asserire
che un certo frammento di codice pascal non poteva essere scritto meglio di come faceva
lui. Tesi dimostratasi ovviamente sbagliata (altrimenti il "grande maestro" non avrebbe
avuto bisogno di attaccarmi con assurde estrapolazioni e basse insinuazioni, utilizzando
per altro terminologie e toni offensive, quasi gli sembrasse impossibile che LUI
POTESSE SBAGLIARE).
In particolare Alex Martelli mi contestava l'uso di intermediari (funzioni e/o procedure
nel caso del pascal, o anche classi visto che il turbo pascal ha costrutti simili alle
classi del C++) nelle operazioni di
allocazione di risorse in linguaggi come il Pascal che non offrono strumenti quali
le eccezioni per gestire le anomalie consentendo il disfacimento di quanto parzialmente
fatto. Il tutto lasciando intendere la nessessita` di introdurre elevati costi.
Premesso, che come qualsiasi programmatore che si rispetti sa, niente e` gratis, se vuoi
qualcosa c'e` un prezzo da pagare. Se magari avesse riflettutto di piu` avrebbe capito
che tali intermediari altro non avrebbero dovuto fare che memorizzare quelle
risorse la cui allocazione puo` potenzialmente fallire, insieme ovviamente alle eventuali informazioni
necessarie al disfacimento. Ad operazione eseguita con successo, sarebbe stato necessario semplicemente
passare la proprieta` di tali risorse a chi ne aveva richiesto l'allocazione.
Considerato che:
1) Se delle risorse devono essere allocate dalle operazioni, questo e` intrinseco nel
    problema e non nella soluzione;
2) Le informazioni per il disfacimento sono necessarie solo se e` il problema a richiederlo e
    cio` e` indipendente dalla soluzione;
3) Il passaggio della proprieta` puo` essere fatto con costi trascurabili o comunque molto
     ridotti (in pascal esistono i puntatori, ma il sig. Martelli sembra non masticare molto il Pascal
     e questo sinceramente mi rende difficile capire la validita` dei suoi interventi in merito)
4) Allocazioni nello heap non sono intrinseche nella soluzione, se le risorse da allocare
    non richiedono tali operazioni.
la soluzione non mi sembra avere costi ecclatanti, specie considerato che tutti i costi vanno
valutati tenendo presente diversi aspetti, tra cui la necessita` di produrre codice facilmente
manutenibile (argomento della iniziale discussione del thread in cui fu portato l'esempio
sulla gestione degli errori) e la natura del problema che si deve risolvere (per applicazioni con molto I/O,
praticamente le piu` diffuse, poche allocazioni nello heap hanno costi trascurabili).
Di sicuro quando invece anche il minimo costo puo` essere significativo, non credo
che si ricorra a linguaggi come il Pascal, ma anche questo Alex Martelli evita accuratamente
di dirlo, cosi` come non tiene conto che il costo di allocazioni nello heap puo` essere comunque
fortemente diminuito utilizzando opportune politiche di allocazione (che qualsiasi programmatore
deve conoscere). 
Per concludere, dato che ormai e` chiaro che tra di noi non corre buon sangue, vorrei invitare
il sig. Martelli ad accettare le incolmabili divergenze in merito a questa specifica
discussione, a non proseguire ulteriormente un discorso che sta trasformandosi in una poco dignitosa lite
(oltremodo  inadatta ad un newsgroup come questo)  e a lasciare alla altrui intelligenza
il compito di valutare le nostre affermazioni evitando di inserire in vari post basse insinuazioni.
Questo ovviamente non vuol dire non ribattere in alcun modo alle affermazioni dell'altro, ma semplicemente
se confronto deve esserci, che sia costruttivo, portando prove a sostegno delle proprie tesi o atte a smentire
quelle altrui, senza ricorrere a estrapolazioni assurde (purtroppo il linguaggio naturale non e` libero dal contesto
come le grammatiche dei linguaggi di programmazione) o a qualunque strumento da talk show televisivo.
Il tutto naturalmente nel thread in cui e` nata la discussione, giacche` spostare la discussione su un  altro
thread senza avvertire l'altro e` quanto meno poco educato (chi le garantiva che io seguissi ancora
questo thread?).
Paolo
 
----------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
  e-mail: 
mar...@cli.di.unipi.it
 
----------------------------------------------------