Newsgroup: it.comp.lang.c++
Titolo: namespace ricerca nomi

Dunque c'è una funzionalità del C++ standard descritta dallo Stroustrup che
non ho riscontrato nel compilatore Borland 5.5 (aderente allo standard) e
vorrei sapere se sono io ad aver capito male la cosa oppure è il compilatore
a non implemtare la "scorciatoia".
nel seguente codice:
namespace my_space
{
  class my_type {......}
  void f(my_type t.......) {;}
}
secondo il libro, io potrei chiamare la funzione f in un qualunque punto del
programma mediante la seguente chiamata:
my_space::my_type a;
f(a);
Anche se f() non si trova nel campo di visibilità del chiamante, il
compilatore dovrebbe cercarlo nel campo di visibilità degli argomenti
(almeno se ho capito bene ciò che vuole dire lo Stroustrup) e quindi
risolvere la chiamata.
Il compilatore, invece, dice che la funzione f non è stata dichiarata.
Ora io chiedo a tutti una cosa:
Quando un compilatore è aderente ad uno standard, è aderente in tutto e per
tutto o è libero di escludere alcune cose?

 Il compilatore, invece, dice che la funzione f non è stata dichiarata.
metti caso che tu abbia dichiarato una funzione f(...) nel namespace globale
(a liv. di modulo), oppure abbia usato la direttiva using per usare la f() di
un altro namespace. quindi per evitare questi casini (che in realtà non puoi
fare, perchè il compilatore giustamente ti dice che è errore), o specifichi
esplicitamente il namespace per ogni elemento appartenente ad esso, oppure usi
la direttiva using per importare nel namespace globale (e quindi evitare di
specificare il nome del namespace ogni volta) solo gli elementi che ti
servono, es.:
    using my_space::f;
ora puoi scrivere:
    my_space::my_type a;
    f(a);
oppure tutto il namespace:
    using namespace my_space;
    my_type a;
    f(a);
ciao :: xaero

 risolvere la chiamata.
(Koenig lookup).  Il tuo codice funziona benissimo con g++ 3.0.1 .
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

 tutto o h libero di escludere alcune cose?
Se e' aderente allo standard e' aderente del tutto. Ci sono delle cose che lo
standard dice che sono implementation defined. In questi contesti il compilatore
puo' fare quello che vuole. In tutti gli altri casi deve fare come dice lo
standard altrimenti non e' aderente allo standard.
Ripeto: Borland 5.5 non e' aderente allo standard.
Anzi: non esiste ancora un compilatore aderente allo standard. C'e' chi lo e' di
piu' e chi lo e' di meno. Ma ancora nessuno lo e' ancora del tutto. Uno dei piu'
aderenti e' il Comeau. Ma anche lui non lo e' ancora del tutto.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 servono, es.:
...
No. Il compilatore non da errore giustamente. Lo da perche' non rispetta il
paragrafo 3.4.2 dello standard. Nel caso presentato da emiliano un compilatore
conforme avrebbe dovuto risolvere la chiamata cosi' come era presentata. Riecco
un esempio (tra l'altro tratto dallo standard):
namespace NS {
    class T { };
    void f(T);
}
NS::T parm;
int main() {
    f(parm);    // OK: calls NS::f
}
Questo meccanismo viene chiamato "Koenig lookup".


 Questo meccanismo viene chiamato "Koenig lookup".
ops!
su Thinking in C++ Vol 1 non viene menzionato, e dice che gli unici metodi per
accedere ai membri di un namespace sono quelli che ho elencato.
forse ancora non era stato aggiunto questo meccanismo allo standard.
chiedo venia ;)
ciao :: xaero

piu' e chi lo e' di meno.
Mi sembri un po' contraddittorio ;)
--
Andrea Laforgia - walkietalkie(at)
libero.it
http://www.geocities.com/AndreaLaforgia

aderenti e' il Comeau. Ma anche lui non lo e' ancora del tutto.
Io non credo che a breve termine esistera' un compilatore
aderente allo standard... per il semplice motivo che non
esiste nessuna autorita' che possa assegnare questo titolo.
L'unica autorita' al momento e' il documento dello standard
e con quello e' *spesso* facile verificare se un compilatore
e' aderente o meno allo standard su una *specifica questione*
e con uno *specifico esempio* (ho detto "spesso" perche' ogni
tanto si incappa in qualche punto in cui il documento
contraddice se stesso in modo evidente).
Anche supponendo il documento dello standard perfetto (cosa
molto lontana dalla realta') verificare se un compilatore
e' completamente aderente allo standard e' una impresa un
po' difficilina... Dubito che Comeau fornira' una
dimostrazione formale che il suo compilatore sia aderente
in tutto e per tutto allo standard e se anche lo facesse ci
vorrebbe del coraggio per accettare una simile dimostrazione
che sarebbe formalmente molto piu' complicata del codice
stesso del suo compilatore... chi verificherebbe che e'
logicamente corretta ?
L'unica possibilita' per affermare che un compilatore e'
standard sarebbe cambiare il significato di "standard" e
dire che e' standard se, ad esempio, supera un set di
test specifici. In questo caso l'affermazione e' facilmente
verificabile e basterebbe sottomettere il set al compilatore
e guardare il comportamento.
Questo ovviamente indebolirebbe moltissimo il concetto
di standard (sarebbe come dire che un programma e' esente
da bug se supera un pacchetto di test; il concetto di
"esente da bug" ne esce un po' malconcio).
In pratica secondo me non esistono compilatori "standard"...
esistono solo compilatori "non-standard" e compilatori
che "non si e' certi che siano non-standard".
Credo che questa situazione durera' ancora per molto
tempo... (e personalmente non ci vedo nulla di male).
Forse Comeau sta per uscire con un compilatore che almeno
prova a dare una implementazione di tutte le feature
indicate nello standard (vedi export per i template).
E' molto ma e' una cosa diversa dal dire che e' un
compilatore conforme al 100% con lo standard.
Al piu' si puo' dire che non vuole essere deliberatamente
non conforme e gia' questo a volte costa.
Ad esempio ho avuto una discussione con uno degli autori
della MetroWerks sul fatto che il documento standard
richieda espressamente una implementazione di
map::operator[] terribilmente inefficiente e lui mi ha
detto che loro, per scelta, hanno ignorato quella parte
del documento di standard per fornire una implementazione
ottimale. Sempre su questo esempio non ho ancora trovato
*nessun* compilatore che abbia rispettato "alla lettera"
quanto viene chiesto dallo standard per map::operator[]
(e non e' che lo standard sia poco chiaro... viene
addirittura fornita una riga di codice C++ che implementa
l'operatore; solo che e' una riga che fa un po' senso :DDD).
Ho anche sottoposto un defect report sulla cosa ma non mi
stupirei di vederlo archiviato come "not-a-defect" (tranne
forse la rimozione di una evidente distrazione del comitato
su make_pair).
Dici che il compilatore Comeau invece rispettera' alla
lettera quanto detto nello standard ? Io spero di no.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 forse ancora non era stato aggiunto questo meccanismo allo standard.
Puo' essere. Ma ricorda che Thinking in C++ e' sostanzialmente un tutorial. Il
fatto che non copra tutto lo standard non dovrebbe stupirti. Per esempio dubito
che parli delle export. E credo ometta anche molti altri particolari.
Comunque non l'ho letto.


 Mi sembri un po' contraddittorio ;)
Gia'. Riscriviamola:
Anzi: non esiste ancora un compilatore aderente allo standard. C'e' chi ci si
avvicina di piu' e chi ci si avvicina di meno.
Ora forse va meglio!


 ottimale.
... snip
Il problema e' conosciuto. Tecnicamente la libreria e il compilatore sono
inscindibili. In pratica per il C++ sono quasi due prodotti diversi. Per la
parte di compilazione questo genere di problema non esiste se non notando che
RTTI, eccezioni e soprattutto l'exception specification rendono il codice molto
meno efficiente. Pero' la soluzione esiste. Il compilatore standard le avrà
abilitate per default (conforme) e permetterà di disabilitarle con degli switch.
Una cosa simile, IMO, dovrebbe essere fatta per le librerie. La versione
standard dovrebbe essere conforme. Poi si puo' aggiungere una seconda versione
piu' ottimizzata (ci sono tanti metodi per farlo, alcuni che permettono anche di
compilare codice scritto per la map standard senza modifiche ma usando la map
ottimizzata).
Che poi gli implementatori preferiscano non implementare del tutto la versione
standard e' una scelta (sulla quale non sono personalmente d'accordo se prima
non cambia lo standard).


Questo meccanismo viene chiamato "Koenig lookup".
Per quale motivo č stata introdotta questa caratteristica nel C++? Non
diminuisce la leggibilitą del codice?
-- 
Marco Barisione (ICQ 84277092)

contraddice se stesso in modo evidente
A riguardo di cosa? Mi puoi fare un'esempio?


 I compilatori per il linguaggio C sono allo stadio D.
Vero per C89 (standard obsoleto), non per C99. Su c.l.c++.m Greg Comeau
cita questo fatto per indicare che a quanto pare la complessita' del
linguaggio non e' l'unico fattore che causa il ritardo nel rilascio di
compilatori conformi al relativo standard.
Ciao,
Nicola

 diminuisce la leggibilità del codice?
Al contrario lo scopo fondamentale e' consentire l'uso della notazione
"intuitiva" degli operatori. In assenza di questo meccanismo operatori
definiti in altri namespace sarebbero invocabili solo con la sintassi
pippo::operator + (a,b);
Ciao,
Nicola

pippo::operator + (a,b);
Già non ci avevo pensato, trovo però che usarlo per casi diversi dagli
operatori possa comunque causare confusione perché non ci si aspetta
di usare una funzione in quel namespace. Sto di nuovo dicendo
cretinate.


 cretinate.
Il problema e' che non puoi decidere se impiegare il meccanismo o meno,
a meno di qualificare sempre sia le funzioni che gli operatori. Tra
parentesi sei in buona compagnia, perche' Herb Sutter tratta questo
argomento nel suo "Exceptional C++" e Scott Meyers l'ha portato a
sostegno della propria opinione che i namespace siano una buona
intenzione che ha fallito lo scopo in un recente thread non mi ricordo
se su comp.lang.c++.moderated o su comp.std.c++ .
Ciao,
Nicola

se su comp.lang.c++.moderated o su comp.std.c++ .
Sono d'accordo con questo (anche se in realtà la mia opinione conta
poco vista la mia poca conoscenza del C++) ma la gestione dei
namespace in C++ mi sembra troppo complicata e i namespace vengono
comunque poco utilizzati. Al contrario è molto semplice quella ad
esempio di python anche se un approccio diverso da quello utilizzato
nel C++ avrebbe creato molti problemi di compatibilità con il codice
già esistente.


 wrote in message
news:3BAB3118...@divalsim.it...

Si. Mi riferivo al C89 (anche perche' il C99 so a malapena che esiste!).


 Sono d'accordo con questo (anche se in realt` la mia opinione conta
Io invece non sono del tutto d'accordo. Molti usano specificare 'using namespace
NS;' ma non e' una buona cosa. Per esempio:
Nota: nell'esempio le semantiche non sono direttamente evidenti, ma non ho
voglia di mettermi a cercare contesti reali decorrelati in cui vi sono procedure
e oggetti sinonimi. Quindi usate la fantasia.
// libreria A
namespace NSA {
    class foobar {
        // bla bla
    };
    void pippo(foobar);
    void pluto(foobar);
    void disney(foobar);
}
// libreria B
namespace NSB {
    class foobar {
        // bla bla
    };
    void paperino(foobar);
    void paperone(foobar);
    void disney(foobar);
}
in questo caso abbiamo evidentemente due librerie distinte con due classi foobar
che sono totalmente non correlate. Per qualche motivo atavico hanno lo stesso
nome (unqualifyed). Per altri atavici motivi esiste anche una omonimia fra le
utility che le gestiscono (disney).
ora supponi di volere scrivere un programma in cui usi entrambe i foobar ma
ovviamente in maniera differente fra loro.
....
    NSA::foobar velivolo;
    NSB::foobar azione;
    // nota che i due nomi sono totalmente decorrelati.
    // le due foobar non hanno alcuna similitudine.
    pippo( velivolo );
    paperino( azione );
...
ha senso. Sappiamo che solo a paperopoli si svolgono azioni, pertanto non ci
verrà mai in mente di scrivere pippo(azione). Inoltre i paperi hanno le ali
pertanto non fanno uso di velivoli. Il codice e' leggibile e consistente ma non
richiede "impazzimenti" con ::
inoltre risulta evidente che
    disney(velivolo); // dinsey significa cambiare la quota
    disney(azione);   // dinsey significa invertire gli effetti
difficile sbagliarsi perche' non puoi cambiare la quota di una azione o
invertire gli effetti di un velivolo.



D'altronde specificare using namespace ti permette
di implementare dei check su una classe potenzialmente
insicura lasciando pulita l'implementazione definitiva
// myvector.h
class MyVector // Una classe poco sicura
{
protected:
  int* buffer;
  int size;
public:
  MyVector(): buffer(0), size(0) {}
  int operator[]( int j ) {
      return buffer[j];
  }
};
// myvectest.h
namespace release
{
#include "myvector.h"
}
namespace TestLimits
{
  struct MyVector : release::MyVector
  {
    int operator[]( int j ) throw(char*)
    {
      if ( j >= size || j < 0 ) // testing pre-condition
        throw " operator[] ";
      return release::MyVector::operator[]( j );
    }
  };
}
namespace ExceptionTest
{
  struct MyVector : release::MyVector
  {
    MyVector() throw(char*) // stressing the client application
    { throw "ctor throwing test exception" ; }
  };
}
//// main.cpp
#include <iostream>
#define TEST ExceptionTest
//#define TEST TestLimits
// questi #define dovrebbe essere ottenuti
// dichiarando nel makefile piu' target
// che si differenziano per l'opzione -D (o equivalente)
#ifndef TEST
#include "myvector.h"
#else
#include "myvectest.h"
  using namespace TEST;
#endif
int main()
{
  try {
    MyVector v;
    int i = v[0]; // Violation access
    std:: cout << i;
  } catch(char *msg) {
    std::cerr << msg;
    return 1;
  }
  return 0;
}
--
ciao
Massimo

> difficile sbagliarsi perche' non puoi cambiare la quota di una azione
In borsa accade sempre :)
--
Luigi
byte...@hotmail.com
http://web.tiscali.it/luigi_web
ICQ #46240443

 se su comp.lang.c++.moderated o su comp.std.c++ .
detta in questo modo potrebbe sembrare che Sutter arrivi alla conclusione 
che la risoluzione di Koening non sia una bella cosa. In realta' scrive 
esplicitamente:
"Comunque e' sufficiente dire che la risoluzione di Koening e' una cosa 
buona e che dovreste essere coscienti di come funziona...".
ciao 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

 buona e che dovreste essere coscienti di come funziona...".
Lungi da me l'intenzione di mettere parole in bocca a Herb Sutter (ne ha
gia' tante, ma questa e' un'altra storia :-) Tra parentesi la mia
opinione personale e' che l'aver problemi con il Koenig lookup e'
soprattutto indicazione di esagerato ricorso alla definizione di
operatori. Salvo che non si stia lavorando con gcc 2.95.x, che in questo
ambito ha almeno un problemone (a causa del quale la versione di allora
della libreria standard di default *non* risiedeva in std)
Ciao,
Nicola

 Si. Mi riferivo al C89 (anche perche' il C99 so a malapena che esiste!).
E' cosi' anche per molti implementatori :-)
Ciao,
Nicola

 E' cosi' anche per molti implementatori :-)
Io ho smesso di usare il C nel 95 (o giu' di li). Mi ritengo "scusato" per non
sapere molto del C99. Ma ti assicuro che se dovessi scrivere un compilatore C,
come minimo mi procurerei lo standard corrente. Una critica che mi e' capitato
di fare agli implementatori di compilatori C++ e' proprio il fatto che insistono
nell'avere uno scwitch per compilare sorgenti C ... che pero' non compilano il C
ma solo il C obsoleto.
Tanto vale che compilino il K&R.
O meglio che si limitino a compilare il C++ (che e' gią abbastanza arduo, come
dimostra il fatto che ancora non ci riescono!).
