Newsgroup: it.comp.lang.c++
Titolo: Perché non funziona?

Salve,
potreste dirmi perché da errore questo codice?
#include <iostream>
#include <list>
int array [] = {0, 1, 2, 3, 4};
list <int> ilist (array, array + 5);
list <int> ilist2 (array + 5, array); <- pensavo non compilasse e invece va!
int main () {
                std::cout << ilist [2[<< std::endl;
            std::cout << ilist2 [2[<< std::endl;                
return 0;
}
Grazie
-- 
Luigi
--
bug windows [5] = {"95", "98", "NT", "Me", "2000"};
togli "tilescarpe" per rispondere via e-mail


Secondo te esiste array +5 ?

 Secondo te esiste array +5 ?
Quando si inizializza un vector con gli elementi di un array si una la
sintassi:
vector<int>ivec (nome_array, nome_array+dimensione+1)
Ciao


non vorrei sbagliarmi, ma allora dovrebbe essere +6. giusto? dimensione è 5
e poi + 1

 e poi + 1
Va be, il + 1 non c'è, cmq array + 5 è giusto. Mettevo + 1 perché mi sono
confuso con il fatto che il primo elemento è 0 e non 1 visto che l'indice
parte da 0


Si, lo so, ovviamente scherzavo :-)
Perché non provi a creare il vector grande 5 e poi inserire gli elementi?
Poi non hai detto esattamente cosa fa, cosa non funziona.

 bug windows [5] = {"95", "98", "NT", "Me", "2000"};
questo che dichiari vuol dire che l'array di nome "windows" di tipo "bug" ha
quattro 5
elementi e gli indici vanno da 0 a 4? Ti e' chiara ora la tua firma?
Toglimi una curiosita' ora:
bug e' un typedef di std::string o un typedef di CString????? (magari e' un
char* ? o const char* ?)
-- 
Posted from [194.214.173.28] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 }
Innanzitutto sbagli ad usare le quadre, dato che usi due parentesi aperte. 
Cmq non per std::list, al contrario ad esempio di vector, non è definito 
operator[]().
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

 operator[]().
Vabe, qui mi è scappata la mano :)
Ciao


 un char* ? o const char* ?)
std::string
Ma cstring non è string per C++? Mi sembra che gli header del C++ sono come 
quelli del C ma con una c davanti e senza .h.
ciao
-- 
Luigi
--
bug windows [5] = {"95", "98", "NT", "Me", "2000"};


 quelli del C ma con una c davanti e senza .h.
di nuovo questa storia...
non mi ricordo nemmeno io la differenza tra cstdlib e stdlib.h.
mi pare che se includi cstdlib tutte le funzioni vengono inserite nel
namespace std, mentre se includi stdlib.h sono nel ns globale.
qualcuno puo' fare chiarezza una volta x tutte? :)
--
ciao
xaero

Già, purtroppo i compilatori sono ancora molto stupidi...
Diciamo piuttosto che il compilatore C++ (per scelta) presuppone
che il *programmatore* sia su queste cose molto intelligente.
Questo non per puro masochismo ma per dare la possiblita' di
scrivere codice scattante.
Io sono contento che il C++ mi permetta di usare anche array
da cui non vengono controllati eventuali sconfinamenti. Se lo
faccio so quali sono i vantaggi e i rischi che questo comporta.
Non c'e' modo su gran parte delle architetture hardware
esistenti di impedire sconfinamenti senza serie penalizzazioni
delle prestazioni... inoltre un errore di sconfinamento fisico
da array non e' secondo me molto meno grave di un errore di
sconfinamento logico (e' peggio un crash o un programma che
termina correttamente ma ha fornito delle risposte errate ?)
In programmazione va usata *comunque* la massima cautela.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 no match for list <int, allocator<int>> &[int]
certo che se non dici in che linea ti da l'errore è un po' più difficile...
cmq è perché, come ti ho detto anche nel post precendente, std::list non 
definisce operator[](), quindi non puoi usare le quadre per accedere agli 
elementi.


 scrivere codice scattante.
si stava parlando di una possibile "non compilazione"; quindi, in teoria, 
il compilatore potrebbe dare almeno un warning dato che è in possesso di 
tutte le informazioni per accorgersi che ci sarà uno sconfinamento. Almeno, 
credo che sia questo che si voleva intendere...
Ciao Anto


credo che sia questo che si voleva intendere...
Il C++ non e' abbastanza espressivo da questo punto di vista.
Anche supponendo che invece di essere iterators di una classe
definita dall'utente (la libreria standard non e' "speciale" da
questo punto di vista) si usassero dei puntatori in cui la
semantica e' definita a livello di linguaggio "core" non c'e'
modo in C++ di dire che la tal funzione deve accettare due
puntatori interni ad uno stesso array in cui il secondo segua
il primo. Non e' un problema di furbizia del compilatore ma di
espressivita' del linguaggio... se tu scrivi
  void memset(void *dest,char value,size_t size);
il compilatore non puo' sapere che se scrivi
  char v[30];
  memset(v,' ',40);
stai "sconfinando". Il prototype di memset non dice abbastanza.
Questi controlli potrebbero essere fatti solamente a runtime
se, ad esempio, un puntatore contenesse al suo interno sempre
sia l'indirizzo dell'array che lo spiazzamento. In questo caso
si potrebbe verificare che due puntatori siano dello stesso
array, che il secondo segua il primo e che nessuno dei due
"sconfini" rispetto all'array.
Questo pero' potrebbe a decadimenti di prestazioni notevoli.
Se proprio voglio cose del genere in C++ posso scrivermele:
io sono contento che il C++ non mi *obblighi* a usare questi
paracarri. Personalmente inoltre credo che questi sconfinamenti
non siano la causa principale dei problemi...
Nota che programmi che fanno controlli simili a quelli che
dici in effetti esistono e assumono molto piu' di quanto e'
strettamente previsto dal linguaggio. Se scrivo
  int foo()
  {
    int *j = new int[100];
    return 3;
  }
io non sto violando nessuna regola C++ ... pero' ci sono
programmi di analisi statica che mi avviserebbero *compile
time* del memory leak. Sono segnalazioni che pero' vanno
prese con le molle e valutate caso per caso ... potrebbe
infatti trattarsi di qualcosa di voluto: ad esempio potrei
aver definito un mio ::operator new che si occupa di
gestire questa memoria... oppure se invece di essere un
array di interi si trattasse di una istanza o di un array
di classi il costruttore potrebbe prendersi cura di
salvare l'indirizzo dell'istanza/e in una struttura dati...
questo non si puo' sapere senza aver analizzato anche
l'implementazione (non solo l'interfaccia) di questo
costruttore.
In genere quando ho provato a usare questi programmi
ultra-intelligenti ho trovato poche segnalazioni utili
in mezzo a molti falsi allarmi.


 stai "sconfinando". Il prototype di memset non dice abbastanza.
hai perfettamente ragione, e infatti avevo previsto una risposta del 
genere. Il problema è che non sono riuscito a esprimermi al meglio. 
Innanzitutto sottolineando che quello che dico è *in teoria*, e che IMHO 
non ha molto senso fare compilatori che riescano a fare anche questo; 
quello che intendevo è che, essenso il costruttore di std::list è un 
template e dato che al momento i compilatori non supportano "export" per 
forza di cose il compilatore aveva a disposizione il codice del 
costruttore, quindi *in teoria*, avrebbe potuto accorgersi che sconfinava.
Evidentemente la mia era più una provocazione che altro...


 stai "sconfinando". Il prototype di memset non dice abbastanza.
Ma se scrivi:
  #include <cstring>
 
  ...
  char v[30];
  std::memset( v, ' ', 40 );
il compilatore ha tutte le informazioni necessarie per sapere che
stai sconfinando, e un buon compilatore potrebbe dare un warning.
Lo stesso vale anche per le altre funzioni della libreria standard,
dato che il compilatore conosce gia' il significato dei parametri
e le eventuali limitazioni.
Per esempio, il gcc controlla se i parametri di printf corrispondono
alla stringa di formattazione, e ovviamente il prototype di printf
non gli basta.
	Mauro

 Andrea

bounds checking...
Ti rispondo semplicemente che eseguire controlli sugli indici dei
vettori significherebbe introdurre un bel pò di codice aggiuntivo che
sicuramente nuocerebbe alle prestazioni del programma, non é un caso
infatti che in linguaggi di più alto livello come il VB(e
probabilmente anche il Delphi)che normalmente eseguono questi
controlli sia stata inclusa l'opzione di eliminarli per avere codice
più veloce.
In C ed in C++ non esiste controllo sugli indici dei vettori
semplicemente perché si tratta di due linguaggi di basso livello, e da
un linguaggio di basso livello solitamente non ci si aspettano tante
comodità, bisogna semplicemente prendere atto che simili controlli
come quello per evitare sconfinamenti siano a carico del programmatore
e non del compilatore.
Tuttavia per chi ci tiene ad avere il bounds check nel C++ ricordo che
la libreria standard mette a disposizione gli std::vector e la
funzione membro 'at' che lancia un eccezione di tipo 'out_of_range'
nel caso si tentasse si accedesse ad un indice del vettore
inesistente.
Ecco un esempio:
    std::vector<int>prova(10);
    try
        {
        /*operazioni sul vector*/
 
prova.at
(10)=1;	//sconfinamento..
        }
    catch(std::exception &err)
        {
        std::cout<<"ECCEZIONE: "<<err.what()<<"\n";
        }
Il Ghenio
-----
ZIO : Fun and games are over with. Anyone who dares
get in my way shall perish.
DIO ci salvi dagli ocx del Viral Basic.
-----

non gli basta.
Si... una bella comodita' (anche se ovviamente non cambia la vita).


bounds checking...
Guarda che se li vuoi in C++ i controlli di sconfinamento te li
puoi implementare. Io sono contento di non essere *OBBLIGATO*
a farne uso.


 altri vasi di Pandora della sintassi).
A questo proposito, è interessante il thread che si sta attualmente
sviluppando su comp.std.c++, da titolo 
   "strict" mode for C++0x
L'intera discussione ruota intorno a una proposta per la prossima
revisione del linguaggio:
 
http://www.animats.com/papers/languages/index.html
Max