GCC can't handle unicode... ?

Started by
12 comments, last by Brobanx 21 years, 5 months ago
Ok, this is giving me big headache. I want my project to be able to use unicode strings (its a console application, sorta like "make"). But for some reason, my compiler (GCC 3.2, mingw edition) doesn't recognise 'wcout', 'wcerr', and 'wendl'. It still recognises wstring, wifstream, etc... however. I checked the standard, and the wcerr, wcout, etc... are defined in >iostream< (reverse the brackets), which I include in my source... but it tells me that 'wcerr', 'wcout', etc... are all undefined. Here's the exact error message: In file included from C:/1/C++/act/CommandLineParser.hpp:4, from C:/1/C++/act/CommandLineParser.cpp:1: C:/1/C++/act/main.hpp: In function `void WarningMessage(const std::tstring&)': C:/1/C++/act/main.hpp:36: `wcout' undeclared in namespace `std' C:/1/C++/act/main.hpp:36: `wendl' undeclared in namespace `std' C:/1/C++/act/main.hpp: In function `void ErrorMessage(const std::tstring&)': C:/1/C++/act/main.hpp:42: `wcerr' undeclared in namespace `std' C:/1/C++/act/main.hpp:42: `wendl' undeclared in namespace `std' In file included from C:/1/C++/act/main.cpp:1: C:/1/C++/act/main.hpp: In function `void WarningMessage(const std::tstring&)': C:/1/C++/act/main.hpp:36: `wcout' undeclared in namespace `std' C:/1/C++/act/main.hpp:36: `wendl' undeclared in namespace `std' C:/1/C++/act/main.hpp: In function `void ErrorMessage(const std::tstring&)': C:/1/C++/act/main.hpp:42: `wcerr' undeclared in namespace `std' C:/1/C++/act/main.hpp:42: `wendl' undeclared in namespace `std' C:/1/C++/act/main.cpp: In function `int main()': C:/1/C++/act/main.cpp:20: `wcout' undeclared (first use this function) C:/1/C++/act/main.cpp:20: (Each undeclared identifier is reported only once for each function it appears in.) In file included from C:/1/C++/act/MakeFileParser.hpp:4, from C:/1/C++/act/MakeFileParser.cpp:1: C:/1/C++/act/main.hpp: In function `void WarningMessage(const std::tstring&)': C:/1/C++/act/main.hpp:36: `wcout' undeclared in namespace `std' C:/1/C++/act/main.hpp:36: `wendl' undeclared in namespace `std' C:/1/C++/act/main.hpp: In function `void ErrorMessage(const std::tstring&)': C:/1/C++/act/main.hpp:42: `wcerr' undeclared in namespace `std' C:/1/C++/act/main.hpp:42: `wendl' undeclared in namespace `std' cpp:20: `wcout' undeclared (first use this function) C:/1/C++/act/main.cpp:20: (Each undeclared identifier is reported only once for each function it appears in.) And it gets that from this code:
      
#ifndef MAIN_HPP

#define MAIN_HPP



#include <tchar.h>

#include <string>

#include <iostream>


#ifdef UNICODE

  #define tcout wcout

  #define tcerr wcerr

  #define tendl wendl

  #define tcin  wcin

  #define tclog wclog

#else

  #define tcout cout

  #define tcerr cerr

  #define tendl endl

  #define tcin  cin

  #define tclog clog

#endif


namespace std {
    typedef basic_string<TCHAR> tstring;
}


inline void
WarningMessage(std::tstring const& message) {
    std::tcout << _T("WARNING: ") << message << std::tendl;
}


inline void
ErrorMessage(std::tstring const& message) {
    std::tcerr << _T("ERROR: ") << message << std::tendl;
}


#endif // MAIN_HPP


      
(UNICODE and _UNICODE are defined when compiling). Do GCC's headers simply not comply to the standard? I find it very odd that they wouldn't support something very common like unicode. (Note also that I'm using the header files included with MingW, not STL port or any 'outside' headers, and I didn't change the include directory lookup through command line switches whatsoever. [edited by - Brobanx on November 30, 2002 3:49:52 PM] [edited by - Brobanx on November 30, 2002 3:51:10 PM]
Advertisement
It all works find here with GCC 3.2.1. Post your code, I'll try it.

Edit: What I tested was some unicode code that I came up with. Your code uses non-standard things that I cannot test, so I was requesting a very mimimal and standards-compliant example of something that doesn't work.



[edited by - Null and Void on November 30, 2002 5:26:38 PM]
you're not allowed to define things in the std namespace. that's a privilege for library implementors.

also what's with std::tstring const& rather than const std::tstring &

[edited by - petewood on November 30, 2002 5:27:36 PM]
Const always makes what''s to its left constant, so I keep it consistent that way. (In const member functions, const goes after the function parameters, etc... this way const is always on the right, it''s a little unconventional but I find it much less confusing, I''m thinking of going to the ''normal way'' of doing this).

Anyway, my project compiles perfectly when I undefine _UNICODE and UNICODE, so, I looked inside the >iostream< header that I use... it depends on a macro _GLIBCPP_USE_WCHAR_T to define the widestring version wcout, wcerr, etc... If I define that macro, then it still complains about wsprintf, and the wide character c-functions not existing, so there''s no quick hack to do this...


I didn''t realize that I couldn''t put that typedef inside the ''std'' namespace, but even after making that change (after putting the typedef into the global namespace), it still complains about the same errors. I find it odd that this is undocumented in the GCC manual, which means I''m probably doing something wrong, but I can''t figure it out for the life of me.
edit: removed my post to do with references as it was incorrect, although there's definitely a difference between const int* and int const*

[edited by - petewood on December 1, 2002 1:12:29 PM]
petewood: You can''t change references to refer to something else. Thats why they were introduced: they have to always point to a valid object (well, you can make a NULL reference, but you have to go out of your way to do it). But your point holds true for pointers.

Member of the Unban Mindwipe Society (UMWS)
- string const& and const string& are strictly equivalent. (petewood: string & const would be different if references weren''t already inherently const).

- <wchar.t> is not a standard header. Your assertion of "no external header" is erroneous.

- You''re defining tcout to be cout (or wcout) when it should be std::cout - and there is no using namespace std; statement before your function declarations.

- You''re not allowed definitions in std as petewood pointed out. You would be allowed specialisations and overloads, but this is not the case (it''s a typedef).
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
quote:Original post by petewood
edit: removed my post to do with references as it was incorrect, although there''s definitely a difference between const int* and int const*


No there''s not - they''re exactly the same.

There''s a difference between, say, int const * and int * const, though. One is a pointer to a constant int, the other is a constant pointer to an int.

If I had my way, I''d have all of you shot!

codeka.com - Just click it.
i see!

thanks for that
quote:Original post by Fruny
- >wchar.t< is not a standard header. Your assertion of "no external header" is erroneous.

- You're defining tcout to be cout (or wcout) when it should be std::cout - and there is no using namespace std; statement before your function declarations.


wchar.t??? Maybe you mean tchar.h, tchar.h simply provides function mapping macros (_tcslen ->strlen or wstrlen, etc...) and the TCHAR typedef / macros. That wouldn't make the compiler not recognise wcout, wcerr.

I use std::tcout, std::tcerr, in my actual code, so once the macros are resolved that becomes std::wcout, std::wcerr. Even when I don't use the macros (and use std::wcout directly) GCC reports the same errors. I don't need 'using namespace std' because I'm refering to std::wcout directly.

I'm thinking there must be some compiler switch I need to specify...

[edited by - Brobanx on December 1, 2002 4:45:53 PM]

[edited by - Brobanx on December 1, 2002 4:46:25 PM]

This topic is closed to new replies.

Advertisement