Newsgroup: it.comp.lang.c++
Titolo: Problema

IL mio compilatore mi lascia scrivere:
class myclass {
         private:
                   const a = 10;
};
Ma è un errore perché solo i membri static possono essere inizializzati.
Vorrei sentire il vostro parere e ringrazio in anticipo.


Di piu', solo i membri static const di tipi interi (short, int, long)
possono essere inizializzati nella dichiarazione della classe.
Ciao,
Nicola

Quella è stata una mia dimenticanza. Proprio io che bado sempre a non
ommettere niente e me la prendo con chi lo fa...
Cmq non mi da nessun warning quando faccio const int a = 10;.

 
Non produce nemmeno un warning?
Anche l'assenza di 'int' viola lo standard.
Max

Grazie infinitamente, queste cose non le conoscevo. 
Ma perché in alcuni codice si trova anche
static const long double = 0.0;
?

 Vorrei sentire il vostro parere e ringrazio in anticipo.
Infatti sia il Borland C++ 5.5 che il DJGPP segnalano un problema.
Quest'ultimo, in particolare, compila lo stesso segnalando che sta
rendendo la variabile static. E dice anche che manca il tipo.
EMG


                          ^
Manca il nome della variabile. Anche corretta a rigor di standard questa
dichiarazione non puo' stare all'interno della dichiarazione di una
classe.
Ciao,
Nicola

Il codice era così, ovvero senza il nome della variabile. Mi sembrava un
errore ma...
Ecco il codice completo copiato dal libro:
class object {
         private:
                  static const long double = 0.0; // nome variabile this
per default 
                  static const long double a = 10.0; 
       //il codice continua ma non è queso il motivo della domanda
};
This è il nome del puntatore che viene aggiunto automaticamente a tutti i
metodi, ma cosa centra con l'esempio sopra?
Anche in questo caso il compilatore tralascia e mi permette una cosa del
genere:
// riferimento a quanto detto sopra
object oggetto;
double a = oggetto.this;
cout << a << endl;
L'output è dieci ma mi chiedo quanto il mio compilatore supporti lo
standard se tralascia  questi errori gravissimi. 
Ammetto cmq  che il libro non è dei migliori.
Grazie Nicola.

Vorrei sentire il vostro parere e ringrazio in anticipo.
compilatore scarsamente standard!
Paolo
--------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
--------------------------------------------------

C'č un motivo per questa strana restrizione? 

C'č un motivo per questa strana restrizione? 
Si, ma ora non ricordo con precisione...
Provo a cercare... intanto si spera in Alex...


 Si, ma ora non ricordo con precisione...
Credo che la ragione sia consentire ai membri static const di essere
trattati come costanti compile-time e permettere le ottimizzazioni
possibili con le costanti integrali (constant folding).
Non so bene se sia un comportamento standard, ma il seguente codice con il
gcc si compila, ma non si linka:
  struct A {
    static const int i = 10;
  };
  int 
  main() {
    const int* p = &A::i;  // undefined reference to `A::i'   
  }
Mentre se scorporo l'inizializzazione di A::i dalla dichiarazione di A,
non vi sono problemi.
Max

possibili con le costanti integrali (constant folding).
Infatti, pero` rimane da spiegare perche` non e` possibile inizializzare
nella classe un membro static const di tipo "valore in virgola mobile"
(ho controllato ed in effetti pare che lo standard parli solo di tipi
integrali).


 non vi sono problemi.
Invece il Borland C++ 5.5 lo compila e linka regolarmente. Chi ha
ragione?
EMG

 integrali).
Credo che le ragioni siano sostanzialmente due: Una legata alla minor
utilita' della dichiarazione interna a quella della classe, per membri
di tipo non intero; infatti l'inizializzazione "immediata" degli interi
e' l'unico modo per utilizzare membri static const come dimensioni di
array, cosa che comunque non sarebbe possibile coi tipi in virgola
mobile.
L'altra e' legata alla diversa gestione dei due tipi di variabili;
mentre le variabili intere si possono tradurre in "letterali" in
linguaggio macchina, ovvero valori espressi direttamente nel codice e su
cui la CPU puo' operare direttamente, questo non e' il caso per i tipi
float e derivati.
Ciao,
Nicola

Ciao,

Credo che abbia ragione gcc, perche' l'omissione della definizione
esterna dei membri statici e' ammissibile solo se il programma non
riferisce esplicitamente l'indirizzo di tali membri.
Ciao,
Nicola

E' un meccanismo di cui non avevo mai sentito, e mi pare anche una
porcheria; questo non lo esclude automaticamente dallo standard, pero'
:-)
Siccome non ho ancora effettuato il fatidico acquisto, non sono in grado
di dire di piu'.
Ciao,
Nicola

 ragione?
Tutti e due: il compilatore non e` TENUTO a diagnosticare l'errore di
violazione della one-definition-rule (errore che comunque e` presente,
quindi gcc non ha torto) se e` in grado in qualche caso particolare
di 'coprire le spalle' al programmatore errante.  Purtroppo.
Alex