Newsgroup: it.comp.lang.c++
Titolo: <string> e <ctype.h>

Standard C library functions toupper( ) and tolower( ) [...]
Dunque, io ho sempre usato le funzioni e le macro che in C erano in
<ctype.h> (come tolower), confidando che venissero opportunamente
ridefinite in <string>. Invece, ho fatto una rapida indagine e ho
scoperto che, ad esempio, l'header "#include <string>" di gcc/g++ e di
bcc55 si limita a includere il "vecchio" ctype.h
Fin qui nulla di male. Il problema è che, a quanto pare, alcuni
compilatori considerano "tolower" appartenente al namespace std, 
altri no.
Ad esempio:
#include <string>
int main()
{
  char ch = 'A';
  ch = tolower(ch);
}
viene compilato da g++2.95 e msvc6, ma non da Bcc55 (Error E2268: Call
to undefined function 'tolower' in function main()), mentre
#include <string>
int main()
{
  char ch = 'A';
  ch = std::tolower(ch);
}
viene compilato da bcc, ma non da g++ (errori vari del parser) né da
msvc (error C2039: 'tolower' : is not a member of 'std').
Chi ha ragione? g++ e msvc, oppure bcc?
-- 
Ciao, Marvin

includere il "vecchio" ctype.h
Che non include i nomi in std mentre <cctype> sì.
-- 
Marco Barisione (ICQ 84277092)

Che non include i nomi in std mentre <cctype> sě.
Mmm, sei sicuro?
Nessuno dei 3 compilatori che uso fa questa distinzione.
Lo header <cctype> di gcc/g++ č questo:
#ifndef __CCTYPE__
#define __CCTYPE__
#include <ctype.h>
#endif
per cui <cctype> e <ctype.h>, per lui, sono identici.
Caso del tutto analogo per Visual C++ e Borland.
Eppure si ha che:
#include <cctype>
int main() { std::tolower(0); }
// bcc: compila
// g++: errori del parser
// msvc: error C2653: 'std' : is not a class or namespace name
mentre:
#include <cctype>
int main() { tolower(0); }
// bcc: Error E2268: Call to undefined function 'tolower' 
// g++: compila
// msvc: compila
Il diverso comportamento č dovuto al fatto che <ctype.h> di g++ e msvc
definisce delle funzioni globali, mentre il <ctype.h> di bcc ha 
#ifdef __cplusplus
namespace std {
#endif /* __cplusplus */
Concludendo: mi piacerebbe sapere cosa dice lo standard in proposito.
-- 
Ciao, Marvin

 Concludendo: mi piacerebbe sapere cosa dice lo standard in proposito.
Lo Standard dice sostanzialmente quello che ti ha detto Marco Barisione.
<ctime> dà accesso alle stesse funzionalità di <ctime.h>, con la
differenza che i nomi vengono definiti all'interno del namespace std.
Ci sono delle eccezioni che a memoria non ricordo. Ad esempio, è previsto
che certi nomi siano messi a disposizione sotto forma di macro. Questi
(per ovvie ragioni) non possono essere vincolati a un namespace
particolare.
Max

differenza che i nomi vengono definiti all'interno del namespace std.
Volevi dire <cctype> e <ctype.h>, suppongo. Comunque la situazione č
del tutto analoga per <ctime> e <time.h>
Se le cose stanno cosě, allora l'unico compilatore che si comporta
correttamente č il Borland.
Chi usa g++ o msvc dovrebbe porre particolare attenzione nell'uso di
queste funzioni: il rischio ovviamente č di ritrovarsi del codice che
non compila piů, se le prossime release saranno piů aderenti allo
standard.
Per riprendere l'esempio dei post precedenti, la seguente versione
compila in tutti i casi:
#include <string>
int main() 
{
  std::string s("Pippo");
  {
    using namespace std;
    s[0] = tolower(s[0]); 
  }
  //[...]
}
-- 
Ciao, Marvin

 standard.
le "prossime" release sono *gia'* piu' aderenti allo standard. Tu ti 
riferisci a g++ 2.9x, ma da tempo e' disponibile la versione 3, che ha 
corretto questo e altri bachi.
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

 Chi ha ragione? g++ e msvc, oppure bcc?
Mumble. Nel primo caso ha ragione solo Bcc55. Per come hai scritto le
cose tolower non deve essere visibile nel namespace globale. Nel secondo
caso hanno ragione tutti e tre. Per come hai scritto le cose tolower
potrebbe essere visibile nel namespace std oppure non essere visibile.
La regola è questa:
1) tolower fa parte delle funzioni del C che il C++ eredita e pertanto
si trova nell'header <ctype.h>.
2) TU hai due modi per usarlo: includere <ctype.h>, nel qual caso hai
tolower nel namespace globale, oppure includere <cctype> nel qual caso
lo hai nel namespace std.
3) l'inclusione del solo <string> POTREBBE comportare la dichiarazione
di tolower oppure no. Se tolower viene dichiarato includendo <string>
deve essere dichiarato nel namespace std (come se fosse stati incluso
<cctype>, NON come se fosse stato incluso <ctype.h>).
--
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