Newsgroup: it.comp.lang.c++
Titolo: Compatibilità differenti compilatori

Salve a tutti. Ho un paio di domande a proposito delle differenze tra alcuni 
compilatori per Windows.
Sto cercando di trasportare un programma che avevo già scritto per il 
compilatore gcc, per renderlo compilabile sul compilatore di Microsoft.
Ho riscontrato il seguente errore che il gcc non segnalava:
//------------------------------------------------------------------
inline int CMicrophone::SaveAudio(SAMPLE* inp,const int num_samples)
{
SHORT WAVBuffer[num_samples];
.....
}
expected constant expression
//------------------------------------------------------------------
Come posso risolvere il problema?
Spero che sia uno dei "soliti" problemi di compatibilità di casting.
Cosa dice lo standard a riguardo?
Non sapendo nè leggere nè scrivere (metaforicamente,almeno per adesso), ho 
sostituito la linea incriminata con:
//------------------------------------------------------------------
SHORT* WAVBuffer=new SHORT[num_samples];
.........
delete[] WAVBuffer;
//------------------------------------------------------------------
Tutto sembra funzionare, ma nella mia applicazione la velocità è una 
priorità, e non so se questa soluzione è
veloce come quella sopra.
A proposito di velocità: sul mio sistema ho a disposizione questi 4 
compilatori:
Microsoft (R) 32-bit C/C++ Standard Compiler Version 13.10.3077 for 80x86 
(mai usato)
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3052 for 80x86
Borland 5.5.1
gcc version 3.2
Qual è quello che genera il codice più veloce (non più velocemente) ?
Spero di non essere OT. Grazie a tutti per eventuali risposte. 

 Spero di non essere OT. Grazie a tutti per eventuali risposte. 
L'ultima domanda in effetti mi pare OT, dato che non riguarda il C++ 
standard. Ovviamente, chiedere su it.comp.programmare.win32 a riguardo 
sarebbe meglio.
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://mbellett.web.cs.unibo.it/
Jabber: RedGlow  - Linux registered user 299762 @ machine 213003

 
Spero ti sia d'aiuto
===
Gianni

 Credo che la differenza sia minimale se non nulla.
Certamente *non* nulla, giacché da una parte abbiamo un'allocazione nello 
stack, mentre dall'altra un'allocazione dinamica (certamente molto più 
dispendiosa in termini di prestazioni).
Così com'è, inoltre, la versione con 'new' non è exception-safe.
Volendo, per riprodurre il costrutto non standard in questione, si può 
ricorrere alla funzione (anch'essa non standard) 'alloca' o '_alloca' 
(vedere documentazione del compilatore o cercare con Google).
Max

 dispendiosa in termini di prestazioni).
Non credo che un compilatore possa trovare algoritmi di allocazione 
molto piu' efficienti, mettendo una struttura dinamica sullo stack 
invece che nello heap. Il vantaggio dello stack e' per l'appunto che, di 
solito, lavori sempre con strutture statiche. Ma, d'altronde, non avendo 
idea di come venga implementata la cosa nel mondo reale (e non 
interessandomi neanche particolarmente), non voglio metterci troppa 
convinzione. E comunque, come da domanda, mi ero limitato all'aspetto 
delle performance.



Questa soluzione non e' sicura rispetto a eccezioni e ritorni 
anticipati. Piuttosto usa la seguente:
   std::vector<SHORT*> WAVBuffer(num_samples);
   // Utilizzato come un array.
   // Si distrugge da solo.
Tuttavia entrambe le soluzioni sono molto piu' lente di un'allocazione 
su stack.
Per avere prestazioni migliori puoi cercare un modo di passare alla 
routine un array gia' allocato, oppure allocare su stack un array di 
dimensione fissa pari al valore massimo che puo' assumere 'num_samples'.
Ma se vuoi ottenere le massime prestazioni devi usare il seguente codice:
   static SHORT WAVBuffer[MaxNumSamples];
in cui 'MaxNumSamples' e' il valore massimo che puo' assumere 'num_samples'.
Questa tecnica non si puo' usare se la routine e' ricorsiva.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 
In realtà, quando si dichiarano variabili locali (a meno che il 
compilatore, ottimizzando, non le allochi su registri macchina) si fa 
implicitamente la stessa operazione che esegue alloca, quindi è 
decisamente efficiente (corrisponde semplicemente a decrementare di un 
tot il registro esp, o poco più), e non serve deallocare.
Nel gcc, alloca() è implementata direttamente dal compilatore... non so 
se il c++ di microsoft faccia altrettanto.
Daniele
P.S. Vale la regola di Knuth, "le ottimizzazzioni premature sono la 
fonte di tutti i mali"

 delle performance.
Allocare una variabile sullo stack corrisponde sostanzialmente a
incrementare (o decrementare) un valore gia' contenuto in un registro.
Invece allocare sullo heap corrisponde a cercare un blocco di
dimensioni sufficienti nella lista dei blocchi liberi, toglierlo da
tale lista se le dimensioni sono sufficientemente simili, altrimenti
spezzarlo in due e riagganciare alla lista il resto, quindi ritornare
il puntatore ottenuto, eventualmente salvando nella word iniziale la
lunghezza del blocco. Se per sfortuna non fosse disponibile un blocco
adeguato, bisognerebbe richiedere altra memoria al sistema operativo.
Parliamo di uno o due ordini di grandezza di differenza.
Ciao,
Nicola