Newsgroup: it.comp.lang.c++
Titolo: Problemi vari di portabilita`

Ciao a tutti.
Sto cercando di rendere "portabile" un mio programma che ho scritto
con Gnu gcc/g++, e cosi` mi sono fatto "prestare" il Borland C++ 5.0 e
il Visual C++ 6.0 per fare delle prove.
Con un bel po' di fatica e di modifiche, alla fine sono riuscito a
ricompilare quasi tutto; pero` sia BC che VC continuano a darmi dei
problemi, specialmente nell'uso del namespace "std". 
Nel seguito riporto alcune delle questioni che, nonostante tutto, non
sono riuscito a capire o ad appianare.
 1) namespace std
Tre piccoli programmi di test, con i commenti sul comportamento dei
vari compilatori:
 - caso A
// file casoA.cpp
#include <iostream>
int main()
{
  cout << "A" << endl;
}
// fine file casoA.cpp
g++ e BC compilano senza problemi.
VC dice:
 error C2065: 'cout' : undeclared identifier
 error C2297: '<<' : illegal, right operand has type 'char [2]'
 error C2065: 'endl' : undeclared identifier
 - caso B
// file casoB.cpp
#include <iostream>
int main()
{
  std::cout << "B" << std::endl;
}
// fine file casoB.cpp
g++ e VC compilano.
BC dice:
 Error casoB.cpp 5: Qualifier 'std' is not a class or namespace name
 in function main()
 - caso C
// file casoC.cpp
#include <iostream>
using namespace std;
int main()
{
  cout << "C" << endl;
}
// fine file casoC.cpp
g++ e VC compilano.
BC dice:
 Error err2.cpp 2: Namespace name expected
Il problema sembra essere che l'<iostream> di BC non definisce un
"namespace std" (casi B e C), e quindi non lo posso usare per "cout",
mentre VC lo richiede espressamente (caso A). L'unico che non mette i
bastoni tra le ruote e` g++, che compila in ogni caso.
In buona sostanza, non sono riuscito a trovare una notazione comune.
Suggerimenti?
 2) Allocazione
Mi piacerebbe sapere come fa g++ a compilare senza nemmeno un warning
il programma che segue:
//// file prova_array.cpp
#include <iostream>
int main()
{
  int n;
  cout<<"n: "; cin>>n;
  double v[n];
  for( int i=0; i<n; ++i )
    v[i]=i;
  for( int i=0; i<n; ++i )
    cout << v[i] << endl;
}
//// fine file prova_array.cpp
Secondo lo standard, n dovrebbe essere una costante, mentre non solo
non lo e`, ma e` una variabile locale che viene modificata dall'utente
un attimo prima della creazione dell'array.
Oppure hanno cambiato lo standard?
 3) Un bug di VC?
Qualche esperto di VC mi saprebbe spiegare la risposta del compilatore
a questo programma, che pure g++ e BC compilano senza problemi?
///// inizio err1.cpp
#include <iostream>
#include <vector>
using namespace std;
class M
{
public: 
  M(int x) { n=x; }
  int get() {return n;}
  friend M operator+( M&, M& );
private:
  int n;
};
M operator+( M& k1, M& k2 )
{
  M res(0.0);
  res.n = k1.n + k2.n;
  return res;
}
int main()
{
  M k(-2);
  cout << (k+k).get() << endl;
}
///// fine err1.cpp
c:/vc98/bin/cl -c -GX -I. -Ic:/vc98/include -o err1.obj err1.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for
80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
err1.cpp
err1.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1786)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more
         information
-- 
Ciao, Marvin

 3) Un bug di VC?
Un iternal error del compilatore e' un bug per
definizione :D. Non dovrebbe esistere nessuna
porcata che data in pasto ad un compilatore lo manda
in confusione sino a quel punto (almeno non dovrebbe
esistere se noi si vivesse in un mondo perfetto).
Comunque quel programma da me compila senza problemi
(VC++ 6.0 SP5) e genera il risultato -4.
Ottengo solo un warning sul fatto che manca lo
statement di return al main (non deve necessariamente
esserci secondo lo standard, ma il VC++ la pensa
diversamente e dice che in questo caso considerera'
main di tipo void).
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 a questo programma, che pure g++ e BC compilano senza problemi?
Lascio la parola agli esperti di VC.
Max

(VC++ 6.0 SP5) e genera il risultato -4.
...che e` il risultato atteso. Quel "SP5" sta per "service pack 5",
suppongo. Io ho la build 12.00.8168
[1]
6.5.3 - The for statement [stmt.for]
-1- The for statement 
     for ( for-init-statement conditionopt ; expressionopt ) statement
is equivalent to 
     {
             for-init-statement
             while ( condition ) {
                     statement
                     expression ;
             }
     } 
-- 
Ciao, Marvin

futuro sarà legale anche in C++.
E` vero, con -pedantic ottengo il warning che mi aspettavo. 
Pensavo che -Wall fosse il massimo livello di warning, ma
evidentemente mi sbagliavo.
-- 
Ciao, Marvin

 C++, che non e` cosa da poco.
Sbagliano proprio. Esiste uno standard che specifica come si deve
comportare un compilatore C++. "C++ Annotations" invece non e' un testo
normativo, ma si limita a descrivere una situazione di fatto.
Il mio sospetto personale e' che l'assunzione di default di std compiuta
da gcc 2.95.x sia uno hack reso necessario da un baco nella gestione del
lookup di operatori in presenza di namespace. Non so come si comporti
gcc 3.0, ma il baco di cui parlo dovrebbe essere gia' stato risolto
negli ultimi snapshot del filone 2.9x
 
Ciao,
Nicola

suppongo. Io ho la build 12.00.8168
Si... il Service Pack 5. La dll che credo essere il cuore del
compilatore (c1xx.dll) e' della build "12.00.8964.0".


 warning) tutte le estensioni non standard.
esiste, basta specificare l'opzione -ansi.
Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 ///// fine err1.cpp
Oltre al compilatore BCC che non funziona (tranne in questo caso che pare
accetti i namespace, strano, no?!?) hai anche il VC++ che non funzia. Da me
compila!
Sicuro di non averci presi in giro ?!?
Alex

 anche se il server ftp della Borland mi sembra un po' stanco...
Si, ma come speri di potrer fare programmi portabili con una versione del
'96 (totalmente pre standard!!!) ?!? Inoltre strano ancora, come gia' ti ho
detto nell'altro messaggio, che l'ultimo esempio compili sotto il tuo BCC,
mah..........
Alex

 esiste, basta specificare l'opzione -ansi.
Oh, grazie, questa proprio mi mancava !
Alex

compilatore (c1xx.dll) e' della build "12.00.8964.0".
Ho trovato il Service Pack 3, che ha risolto il problema dell'
"internal compiler error" (dalle prove che avevo fatto, pare che VC si
incasinasse con i friend operator all'interno di un namespace).
Anche bcc55 e` molto soddisfacente: come molti mi avevano gia` fatto
notare, a differenza della 5.0 gli oggetti definiti in iostream sono
nel namespace std.
In definitiva, ho raggiunto il mio scopo, cioe` rendere portabile (per
quanto possibile) il sorgente della classe che uso quando mi servono
delle matrici in C++. [Nel caso qualcuno fosse interessato: fa le
solite cose (determinante, inversa, autovalori e autovettori, svd,
Cholesky, Gauss-Jordan, ecc.) ma e` semplice sia da usare che da
compilare. Si trova in
http://digilander.iol.it/tafkam/mat/mat_intro.html
 ]. 
Grazie ancora a tutti quelli che, in pieno ferragosto, hanno avuto la
pazienza di rispondere ai miei post.
-- 
Ciao, Marvin

 Ha ragione VC++ !
ne approfitto per ricordare che e' uscito da tempo gcc 3.0 che ha risolto 
questo e altri numerosi bug: 
http://gcc.gnu.org
Ciao Anto
