Newsgroup: it.comp.lang.c++
Titolo: inizializzazione puntatori

Un collega tedesco mi ha inviato questo frammento di codice, perche' secondo
lui e' corretto, ma non funziona.
class CPuffertabelleElement
{
   private:
      char*            m_pszValue;
   public:
      // template method
      template <class T>
      void GetValue (T &wert)
      {
        wert   = * (T *) m_pszValue;
      }
};
Ho suggerito di inizializzare il puntatore m_pszValue, eventualmente nel
costruttore:
...
public:
   CPuffertabelleElement (char *pc): m_pszValue(pc) {}
...
Lui insiste, citando addirittura Stroustrup, che questo non dovrebbe essere
necessario.
Qualcuno ha opinioni/suggerimenti?
Diversi compilatori hanno diversi comportamenti con quel codice: qualcuno
compila regolarmente, ma poi il programma va in crash, un altro segnala
errore in compilazione. Cosa ci si dovrebbe aspettare da un compilatore
aderente allo standard?
Grazie in anticipo.
Francesco

 Francesco
Per esempio a me questo codice compila e linka regolarmente ma poi
al run time mi da un Access Violation alla riga dove viene eseguito il cast.
// prova cast.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class CPuffertabelleElement
{
   private:
      char*            m_pszValue;
   public:
      // template method
      template <class T>
      void GetValue (T &wert)
      {
        wert   = * (T *) m_pszValue;
      }
};
int main(int argc, char* argv[])
{
 CPuffertabelleElement c;
 float a;
 c.GetValue(a);
 return 0;
}

il compilatore usato?
In effetti, i compilatori che ho potuto provare io fanno esattamente quello
che descrivi tu: compilazione ok, crash in esecuzione. In win ho una
violazione d'accesso, nell'ambiente target, che e' senza OS, un crash che si
spiega bene col puntatore impazzito; ma in effetti il valore del puntatore
non inizializzato forse e' nullo essendo membro di una classe (?).
L'errore in compilazione lo ha verificato l'autore con il Borland C++ 5.02 e
non so quale sia esattamente.
Da qualche parte dovrei avere un Borland; appena riesco provo anche con
quello.
Grazie ancora per l'aiuto.
francesco

 standard?
Credo dovrebbe compilarlo. (Nota che alcuni compilatori potrebbero avere
problemi con i membri template.) Quello che poi accadrà in esecuzione
dipenderà dal valore assunto da pszValue.
Max


waiting... (io il borland non ce l'ho!) :)


aderente allo standard?
Quello che succede e' che il valore del puntatore e' lasciato al caso ed
il suo uso ha comportamento indefinito (se fosse possibile anche il "big
bang"!).
Paolo

non so quale sia esattamente.
Ne dubito, il BC++5.02 non supporta i member template...
comunque al piu' dovrebbe essere una warning.
Paolo

 al run time mi da un Access Violation alla riga dove viene eseguito il cast.
Il DJGPP non genera alcun errore neanche in esecuzione. E' normale?
EMG

lui e' corretto, ma non funziona.
Riporto una breve rassegna delle prove che ho fatto, solo per completezza.
Il problema originario per quel che mi riguarda e' chiarito.
Grazie a tutti.
MSVC6.0 compila regolarmente e va in crash in esecuzione;
Borland C++ 5.3 segnala errore in compilazione:
Declaration terminated incorrectly
alla riga che contiene template <class T> (non supporta membri template?)
Borland C++ 5.5 compila regolarmente e va in crash in esecuzione
Gcc in Linux compila regolarmente e va in crash in esecuzione
(segmentation fault)
DJGPP compila regolarmente e _non_ va in crash in esecuzione
(segnalato da EMG e verificato anche da me).
D'altra parte se, come si e' detto, un puntatore non inizializzato
ha effetti imprevedibili, potrebbe anche non fare nulla di particolare (?)
Francesco

Il DJGPP non genera alcun errore neanche in esecuzione. E' normale?
Si, comportamento indefinito vuol dire anche che apparentemente tutto va
bene. Se non erro poi DJGPP e' un compilatore dos e sotto dos non
ci sono meccanismi di protezione, di conseguenza avresti seri problemi
solo se tramite il puntatore vai a toccare aree sensibili come la
tabella degli interrupt.
Paolo