Newsgroup: it.comp.lang.c++
Titolo: Estensione Microsoft __declspec(novftable)

Qualcuno sa come mai questa __declspec (che evita il codice di
inizializzazione della vftable all'interno dei ctor/dtor, con ovvi vantaggi)
non sia una ottimizzazione adottata di default dai compilatori su tutte le
classi astratte (con almeno un metodo puro, e quindi non instanziabili)?
Ciao
-----
Giovanni Bajo
Lead Programmer
Prograph Research S.r.l.
http://www.prograph.it

 classi astratte (con almeno un metodo puro, e quindi non instanziabili)?
Perche` la semantica dello standard C++ non lo permette.
Quando un costruttore sta venendo eseguito, e` _permesso_
chiamare da esso, direttamente o indirettamente, dei metodi
virtuali (non puri), ed essi devono essere correttamente risolti
"come se" la classe corrente fosse la piu` derivata (anche se
non e` istanziabile).
Ad esempio:
    #include <iostream>
    struct base {
        virtual void say() { std::cout << "base!\n"; }
        virtual void rendinonistanziabile() = 0;
        base() { say(); }
    };
    struct deriv: public base {
        virtual void say() { std::cout << "deriv!\n"; }
        virtual void rendinonistanziabile() {}
        deriv() { say(); }
    };
    deriv dede;
DEVE emettere su stdout ESATTAMENTE:
base!
deriv!
Se non lo fa, il compilatore e` in violazione dello
standard.
Specificare che e` un errore chiamare metodi
virtuali nel costruttore (o distruttore) avrebbe
forse potuto essere meglio, ma, ahime`, cosi`
e` ormai lo standard del C++.
Alex

 non e` istanziabile).
Davvero?? Mi giunge nuova ... beh, non si smette mai di imparare :))
A occhio avrei detto che non era possibile completamente richiamare membri
virtuali dal costruttore...
Allora rigiro la domanda: come mai la __declspec non viene adottata di
default su tutte le classi astratte i cui costruttori non richiamano alcuna
funzione virtuale?
P.S: arrivo a concepire qualche cosa di ereditarierà multilevello in cui
effettivamente serve l'inizializzazione passo passo della vftable per
accondiscendere lo standard, ma se mi fai l'esempio tu faccio prima :)
Bye


 non e` istanziabile).
Sei sicuro? Ero convinto che la chiamata a un metodo virtuale in un
costruttore fosse risolta in modo statico, ovvero chiamando
l'implementazione fornita nella stessa classe cui appartiene il
costruttore.
Se funziona come dici tu mi pare pericolosissimo, perche' dalla classe
base ovviamente non si puo' garantire che un override di un metodo
virtuale non faccia conto sullo stato proprio della classe derivata in
cui e' implementato, che durante l'esecuzione del costruttore non e'
disponibile.
Ciao,
Nicola

 funzione virtuale?
Perche` non e` in generale possibile determinare se questo
richiamo avvenga o meno (col solito vincolo di compilazione
separata).  [occorre che la condizione sia soddisfatta anche
nei distruttori, naturalmente].
Nulla impedisce ad un particolare compilatore di fare una
data ottimizzazione se e quando e` in grado di provarne
l'idempotenza (vedi la "as-if"-rule dello Standard C++).
La possibilita` di asserire direttamente questa idempotenza
e` pero` preziosa, perche` puo` risultare applicabile in
molti casi in cui il compilatore non potrebbe dimostrare
quanto si desidera.
Un "linguaggio delle pre-condizioni" non basterebbe, se
non avesse una potenza praticamente infinita (e, se la
avesse, l'ottimizzatore dovrebbe a sua volta avere una
potenza illimitata per trarne tutte le deduzioni ammesse
e utili; inoltre, si cadrebbe nella trappola Goedeliana --
nessun sistema formale abbastanza potente per modellare
l'aritmetica intera puo` essere assieme coerente & completo).
Sicuramente una sua utilita` l'avrebbe, ma solo collaterale e 
ausiliaria, proprio come "assert" e simili utili ausilii gia hanno.
Alex

 > "come se" la classe corrente fosse la piu` derivata (anche se
cioe` nessuna classe ulteriormente derivata viene presa 
in considerazione nella costruzione delle vtable (le basi
virtuali complicano assai la vita, naturalmente -- *ick*!-).
Alex

 nei distruttori, naturalmente].
Noto che sei un esperto di standard c++.
A questo punto mi piacerebbe porti due domande.
1) quale libro mi consigli per imparare bene le specifiche dello STANDARD 
c++
2) se io dichiaro e definisco un template in un .h e poi voglio esportare 
l'istanza di questo template a cui passo come parametro una classe, come 
devo fare in maniera standard? In Visual C++ mi basta mettere in un .h 
una cosa del genere :
template class _declspec(export) miotemplate<miaclass>

 devo fare in maniera standard?
Lo standard C++ non prevede l'esistenza di DLL o altre forme
di librerie a caricamento dinamico, quindi non c'e` risposta, sigh.
Alex

 l'aritmetica intera puo` essere assieme coerente & completo).
Di questo mi pare ne abbiamo già discusso abbastanza :) E comunque mi sono
abbastanza convinto dell'irrealizzabilità di un linguaggio formale del
genere.
