Newsgroup: it.comp.lang.c++
Titolo: Array in C++ vs array in C

Il seguente spezzone di codice compila (e gira) correttamente se dato in
pasto al compilatore "c++" di GCC 3.2, mentre con Visual C++ 6 segnala
errore "Constant value expected" in corrispondenza della dichiarazione
dell'array.
AFAIK il codice e' corretto, perche' a differenza di quanto accade in C, in
C++ e' possibile indicare valori calcolati per la dimensione degli array,
che verra' calcolata a run-time.
C'e' un modo per far accettare il codice a Visual C++?
int funz()
{
    return 4;
}
int main()
{
    int x=funz();
    int v[x];
    v[0]=5;
    cout << v[0] << endl;
    return 0;
}

 degli array, che verra' calcolata a run-time.
Ma non e' un'estensione specifica del gcc questa?
Saluti.

 che verra' calcolata a run-time.
No. Le regole del C (quello classico, C89) e del C++ a questo riguardo non
differiscono.
Gli array automatici con dimensione definita a run-time sono un'estensione
del GCC, che VC++ legittimamente non riconosce.
Il costrutto in questione è stato invece introdotto nello Standard del C99.
Max

 dichiarazione dell'array.
Visual C++ 6 è vecchio, e, all'epoca, quello era un costrutto illegale. 
Per ora puoi usare la funzione non-standard alloca()
-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.3. C, C++ and ASM developers
                               and beta testers are welcome!

 C'e' un modo per far accettare il codice a Visual C++?
Come ti è stato detto, quel codice è compilabile in C99.
Immagino che nell'ultima versione del VC++ (7.1) si possa impostare
anche il C99 come linguaggio, ma non ne sono certo.
Comunque quel codice è giusto che NON compili in C++.
Piuttosto puoi fare:
#include <vector>
int x=funz();
std::vector<int> v[x];
sfruttando quel che fornisce il C++ nella libreria standard.
-- 
Gerolamo

 sfruttando quel che fornisce il C++ nella libreria standard.
ciao


 Perche' dovrebbe utilizzare alloca() e rinunciare alla portabilita' ,e non
a questo punto allocare l'array dinamicamente?
Ivan

 forse volevi mettere le parentesi tonde ???
Si, scusa. Mi è scappato dal taglia-incolla.
Correggo:
std::vector<int> v(x);
-- 
Gerolamo

 ,e non a questo punto allocare l'array dinamicamente?
perchè è l'esatto equivalente: non richiede grandi modifiche al codice, 
il comportamento a runtime è identico, ecc. Comunque, tutto dipende dal 
suo obiettivo: se si tratta solo di fare un porting di codice esistente 
può usare il mio suggerimento; altrimenti se quello che vuole è rendere 
il codice portabile, non può farlo e deve cambiare strategia


> Per ora puoi usare la funzione non-standard alloca()
esempio:
int main()
{
    int x=funz();
#ifdef __GNUC__
    int v[x];
#else
    int * v = new(alloca(sizeof(int) * x)) int;
#endif
    v[0]=5;
    cout << v[0] << endl;
    return 0;
}
Considerando i problemi causati da:
 - scrivere esplicitamente sizeof(tipo) per l'allocazione
 - usare in C++ un puntatore come un array
 - alloca() in quanto tale
forse è meglio lasciar perdere


}
L'uso dei vector (comunque comodissima) determina un tempo d'esecuzione
maggiore di circa 2.5 volte.
-- 
Saluti,
Andrea (uno dei tanti)
mailto:
acola...@bigfoot.com

 maggiore di circa 2.5 volte.
penso solo in inserimento ... negli usi comuni di indicizzazione dovrebbe
creare pochissimo over anzi direi nullo se ottimizzato inline ... no ???
le parti cove va a creare over e' l'inserimento copia ecc ... che richiedono
cicli di controllo allocazioni e di allocazione memoria ed inizializzazione
(forse successivamente alla creazione non dovrebbe piu' fare
inizializzazione su nuovi elementi no ???)


ehm no, almeno per esperienza personale:
ho usato entrambe le possibilità (vector o puntori ad array) per la
memorizzazione (unica) di bitmap, per una loro successiva elaborazione
(dunque con il solo accesso indicizzato, ma in numero di volte dell'ordine di
1000) e il rapporto dei tempi è stato in media quello sopra citato.


 sopra citato.
mmm... hai valutato anche l'opzione valarray?
Non so se erano adatti al tuo scopo, ma prestazionalmente sono
sicuramente notevoli.
In alcuni miei benchmark andavano addirittura meglio degli array puri.
-- 
Gerolamo

In alcuni miei benchmark andavano addirittura meglio degli array puri.
Uhm... io, pensando all'uso degli elementi dell'array, ognuno singolarmente,
non li ho presi in considerazione. 


 }
Non ti consiglio di fare una cosa del genere.
"alloca" non alloca memoria dinamica ma sullo stack frame  e viene
disallocata al momento dell' uscita dallo scope della funzione chiamante,
quindi utilizzare l'operatore new di default con la dislocazione a un
puntatore allocato sullo stack in questo modo non potrebbe che crearti
problemi sia in caso di delete, sia in caso ti capiti di dover tornare il
puntatore.

 il comportamento a runtime è identico, ecc. Comunque, tutto dipende dal
Non e' l'esatto equivalente, in quanto la funzione "alloca", alloca memoria
sullo stack frame e non nell' heap.
Ivan

...

Non capisco il tuo commento. Si stava discutendo di come riprodurre un
costrutto non standard in C++ (offerto dal GCC e disponibile nel C99)
mediante l'impiego della funzione 'alloca'. Quindi il fatto che
l'allocazione avvenga sullo stack è ben noto all'autore(/-trice) ed è il
cuore di tutta la discussione. In secondo luogo, usare 'delete' con un
puntatore restituito da un placecement new è comunque un errore, quindi il
problema non si pone.
Ad ogni modo, nel caso in questione, non vedo l'utilità ricorrere al
placement new: un semplice cast è sufficiente.
Max

 puntatore restituito da un placecement new è comunque un errore,
La mia obiezione era sulla mancanza di necessiata' di allocare l'array per
forza nello stack utilizzando una funzione per di piu' non standard,
anziche' ricorrere all'utilizzo di memoria dinamica.
Tanto piu' che l'area dati che puo essere allocata nello stack e' molto piu'
limitata di quella disponibile nell' heap, per cui per array di grandi
dimensioni non potrebbero essere gestiti.
Ivan