Visualizzazione post con etichetta compilazione. Mostra tutti i post
Visualizzazione post con etichetta compilazione. Mostra tutti i post

lunedì 3 gennaio 2011

C++: problemi con copia oggetti stream

Il seguente errore di compilazione (probabilmente contornato da alcune altre righe relative al nostro specifico codice) restituito dal compilatore g++ per un programma scritto in C++ è sintomo di un problema molto specifico e subdolo:

/usr/include/c++/4.4/bits/ios_base.h:
In copy constructor ‘std::basic_ios< char,
std::char_traits< char> >::basic_ios(const std::basic_ios< char,
std::char_traits< char> >&)’:
/usr/include/c++/4.4/bits/ios_base.h:790: error:
‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.4/iosfwd:47: error: within this context
/usr/include/c++/4.4/iosfwd:
In copy constructor ‘std::basic_ofstream< char,
std::char_traits< char> >::basic_ofstream(const std::basic_ofstream< char,
std::char_traits< char> >&)’:
/usr/include/c++/4.4/iosfwd:84:
note: synthesized method ‘std::basic_ios< char,
std::char_traits< char> >::basic_ios(const std::basic_ios< char,
std::char_traits< char> >&)’ first required here
/usr/include/c++/4.4/streambuf:
In copy constructor ‘std::basic_filebuf< char,
std::char_traits< char> >::basic_filebuf(const std::basic_filebuf< char,
std::char_traits< char> >&)’:
/usr/include/c++/4.4/streambuf:770:
error: ‘std::basic_streambuf< _CharT, _Traits>::
basic_streambuf(const std::basic_streambuf< _CharT, _Traits>&)
[with _CharT = char, _Traits = std::char_traits< char>]’ is private
/usr/include/c++/4.4/iosfwd:78: error: within this context
/usr/include/c++/4.4/iosfwd:
In copy constructor ‘std::basic_ofstream< char,
std::char_traits< char> >::basic_ofstream(const std::basic_ofstream< char,
std::char_traits< char> >&)’:
/usr/include/c++/4.4/iosfwd:84:
note: synthesized method ‘std::basic_filebuf< char,
std::char_traits< char> >::basic_filebuf(const std::basic_filebuf< char,
std::char_traits< char> >&)’ first required here

Tutte queste parole in realtà possono essere sintetizzate in questo modo: state cercando di copiare un oggetto che non può essere copiato. L'oggetto in questione è, in questo caso, uno stream della libreria standard (nel mio caso era un oggetto della classe ofstream).
Importante è ricordare che anche quando si passa un oggetto (o, più in generale, una variabile) ad una funzione il codice corrispondente all'invocazione della funzione genererà una copia dell'oggetto passato, anche in questo caso si compie quindi un'operazione non valida e il compilatore ci dirà, in modo non troppo chiaro, che stiamo sbagliando.

La soluzione al problema è molto semplice: è sufficiente modificare la funzione e la sua invocazione in modo che quello ad essere passato sia il riferimento (cioè il puntatore) all'oggetto e non l'oggetto stesso.

Versione errata:
  class myclass {  
...
public:
void print(ofstream file) const;
};

[...]

ofstream file;
file.open(filename,ios::out);
myclass obj();
obj.print(file);

Versione corretta:
  class myclass {  
...
public:
void print(ofstream *file) const;
};

[...]

ofstream file;
file.open(filename,ios::out);
class obj();
obj.print(&file);

mercoledì 6 ottobre 2010

GCC: compilare codice a 32bit su sistemi a 64bit

Per riuscire a compilare correttamente codice a 32bit su sistemi a 64bit è necessario che siano disponibili sul sistema anche le versioni a 32bit delle librerie richieste.
Tale versione delle librerie (32bit) non vengono, di solito, installate di default sui sistemi a 64bit.

Per esperienza personale, quando si hanno problemi di compilazione, dovuti alla generazione di applicazioni 32bit su macchine a 64bit, nella maggior parte dei casi si può risolvere il problema installando i seguenti pacchetti su sistemi Ubuntu (con gcc già installato):
 sudo apt-get install libc6-dev-i386 
o in alternativa
 sudo apt-get install gcc-multilib 
e questi su sustemi Fedora/RedHat (con gcc già installato):
 yum install glibc-devel.i686 libgcc.i686 


Se i suddetti pacchetti non sono installati, tipici errori che si ottengono in fase di compilazione e linking sono (in assenza di libc6-dev-i386 o glibc-devel.i686):
 [...]
/usr/include/gnu/stubs.h:7:27: error:
gnu/stubs-32.h: No such file or directory
e (su sistemi Fedora/RedHat, in presenza di glibc-devel.i686 ma assenza di libgcc.i686):
 [...]/ld: cannot find -lgcc_s 
[...]
collect2: ld returned 1 exit status