std::wcout and const char *

Discussion in 'C++' started by Erik Knudsen, Dec 11, 2007.

  1. Erik Knudsen

    Erik Knudsen Guest

    Hi!

    In converting applications from ansi to unicode, it is a problem that
    the std::wcout accepts a const char * without complaining compile time.

    This compiles and runs:
    ------------------------------
    const char *lookup()
    {
    return "Hello world";
    }
    std::wcout << lookup();
    ------------------------------

    I would like it to fail compile time, so I can properly convert cases
    like this to unicode in a meaningful way.

    Any ideas?


    Regards,
    Erik Knudsen
     
    Erik Knudsen, Dec 11, 2007
    #1
    1. Advertising

  2. Erik Knudsen

    Stefan Naewe Guest

    On 12/11/2007 10:16 AM, Erik Knudsen wrote:
    > Hi!
    >
    > In converting applications from ansi to unicode, it is a problem that
    > the std::wcout accepts a const char * without complaining compile time.
    >
    > This compiles and runs:
    > ------------------------------
    > const char *lookup()
    > {
    > return "Hello world";
    > }
    > std::wcout << lookup();
    > ------------------------------
    >
    > I would like it to fail compile time, so I can properly convert cases
    > like this to unicode in a meaningful way.
    >
    > Any ideas?


    Declare and do not define std::eek:perator<<(wostream&, char const*) yourself?

    namespace std
    {
    inline
    wostream& operator<<(wostream& wos, const char*);
    }


    Just an idea...


    S.
    --
    Stefan Naewe stefan dot naewe at atlas-elektronik dot com
    Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
    Plain text mails only, please http://www.expita.com/nomime.html
     
    Stefan Naewe, Dec 11, 2007
    #2
    1. Advertising

  3. Erik Knudsen

    Erik Knudsen Guest

    Stefan Naewe wrote:

    >> I would like it to fail compile time, so I can properly convert cases
    >> like this to unicode in a meaningful way.
    >>
    >> Any ideas?

    >
    > Declare and do not define std::eek:perator<<(wostream&, char const*) yourself?
    >
    > namespace std
    > {
    > inline
    > wostream& operator<<(wostream& wos, const char*);
    > }
    >
    >
    > Just an idea...



    Thanks, but wouldn't that just give me a linker error, with no reference
    to code lines?


    Regards,
    Erik Knudsen
     
    Erik Knudsen, Dec 12, 2007
    #3
  4. Erik Knudsen

    Stefan Naewe Guest

    On 12/12/2007 10:01 AM, Erik Knudsen wrote:
    > Stefan Naewe wrote:
    >
    >>> I would like it to fail compile time, so I can properly convert cases
    >>> like this to unicode in a meaningful way.
    >>>
    >>> Any ideas?

    >>
    >> Declare and do not define std::eek:perator<<(wostream&, char const*)
    >> yourself?
    >>
    >> namespace std
    >> {
    >> inline
    >> wostream& operator<<(wostream& wos, const char*);
    >> }
    >>
    >>
    >> Just an idea...

    >
    >
    > Thanks, but wouldn't that just give me a linker error, with no reference
    > to code lines?


    Yes...but:

    If I call 'g++ -g' the linker gives me the file and line number:


    g++ -g -Wall wchar.cc -o wchar
    /tmp/ccLf8VPM.o: In function `main':
    wchar.cc:37: undefined reference to `std::eek:perator<<(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&, char const*)'
    collect2: ld returned 1 exit status
    make: *** [wchar] Fehler 1


    HTH

    S.
    --
    Stefan Naewe stefan dot naewe at atlas-elektronik dot com
    Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
    Plain text mails only, please http://www.expita.com/nomime.html
     
    Stefan Naewe, Dec 12, 2007
    #4
  5. Erik Knudsen

    Stefan Naewe Guest

    On 12/12/2007 10:11 AM, Stefan Naewe wrote:
    > On 12/12/2007 10:01 AM, Erik Knudsen wrote:
    >> Stefan Naewe wrote:
    >>
    >>>> I would like it to fail compile time, so I can properly convert cases
    >>>> like this to unicode in a meaningful way.
    >>>>
    >>>> Any ideas?
    >>> Declare and do not define std::eek:perator<<(wostream&, char const*)
    >>> yourself?
    >>>
    >>> namespace std
    >>> {
    >>> inline
    >>> wostream& operator<<(wostream& wos, const char*);
    >>> }
    >>>
    >>>
    >>> Just an idea...

    >>
    >> Thanks, but wouldn't that just give me a linker error, with no reference
    >> to code lines?

    >
    > Yes...but:
    >
    > If I call 'g++ -g' ...


    and remove the 'inline'...

    > the linker gives me the file and line number:
    >
    >
    > g++ -g -Wall wchar.cc -o wchar
    > /tmp/ccLf8VPM.o: In function `main':
    > wchar.cc:37: undefined reference to `std::eek:perator<<(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&, char const*)'
    > collect2: ld returned 1 exit status
    > make: *** [wchar] Fehler 1


    I don't know why I put 'inline' there a all...

    S.
    --
    Stefan Naewe stefan dot naewe at atlas-elektronik dot com
    Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
    Plain text mails only, please http://www.expita.com/nomime.html
     
    Stefan Naewe, Dec 12, 2007
    #5
  6. Erik Knudsen

    James Kanze Guest

    On Dec 11, 10:51 am, Stefan Naewe <> wrote:
    > On 12/11/2007 10:16 AM, Erik Knudsen wrote:


    > > In converting applications from ansi to unicode, it is a
    > > problem that the std::wcout accepts a const char * without
    > > complaining compile time.


    > > This compiles and runs:
    > > ------------------------------
    > > const char *lookup()
    > > {
    > > return "Hello world";
    > > }
    > > std::wcout << lookup();
    > > ------------------------------


    > > I would like it to fail compile time, so I can properly
    > > convert cases like this to unicode in a meaningful way.


    > > Any ideas?


    > Declare and do not define std::eek:perator<<(wostream&, char
    > const*) yourself?


    > namespace std
    > {
    > inline
    > wostream& operator<<(wostream& wos, const char*);
    > }


    > Just an idea...


    That's undefined behavior. You're not allowed to define new
    free functions in a std::.

    The standard std::wostream defines an operator<< for char
    const*. You have to assume that some of the other operator<<
    for wostream may use it, so you really have to leave it.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Dec 12, 2007
    #6
  7. Erik Knudsen

    Stefan Naewe Guest

    On 12/12/2007 1:41 PM, James Kanze wrote:
    > On Dec 11, 10:51 am, Stefan Naewe <> wrote:
    >> On 12/11/2007 10:16 AM, Erik Knudsen wrote:

    >
    >>> In converting applications from ansi to unicode, it is a
    >>> problem that the std::wcout accepts a const char * without
    >>> complaining compile time.

    >
    >>> This compiles and runs:
    >>> ------------------------------
    >>> const char *lookup()
    >>> {
    >>> return "Hello world";
    >>> }
    >>> std::wcout << lookup();
    >>> ------------------------------

    >
    >>> I would like it to fail compile time, so I can properly
    >>> convert cases like this to unicode in a meaningful way.

    >
    >>> Any ideas?

    >
    >> Declare and do not define std::eek:perator<<(wostream&, char
    >> const*) yourself?

    >
    >> namespace std
    >> {
    >> inline
    >> wostream& operator<<(wostream& wos, const char*);
    >> }

    >
    >> Just an idea...

    >
    > That's undefined behavior. You're not allowed to define new
    > free functions in a std::.


    I knew someone would say that...

    But really: Who cares in this case if it just works (with some
    modifications and only (?) with g++ (see my other post)) ?


    > The standard std::wostream defines an operator<< for char
    > const*. You have to assume that some of the other operator<<
    > for wostream may use it, so you really have to leave it.



    S.
    --
    Stefan Naewe stefan dot naewe at atlas-elektronik dot com
    Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
    Plain text mails only, please http://www.expita.com/nomime.html
     
    Stefan Naewe, Dec 12, 2007
    #7
  8. Erik Knudsen

    James Kanze Guest

    On Dec 12, 2:40 pm, Stefan Naewe <> wrote:
    > On 12/12/2007 1:41 PM, James Kanze wrote:


    > > On Dec 11, 10:51 am, Stefan Naewe <> wrote:
    > >> On 12/11/2007 10:16 AM, Erik Knudsen wrote:


    > >>> In converting applications from ansi to unicode, it is a
    > >>> problem that the std::wcout accepts a const char * without
    > >>> complaining compile time.


    > >>> This compiles and runs:
    > >>> ------------------------------
    > >>> const char *lookup()
    > >>> {
    > >>> return "Hello world";
    > >>> }
    > >>> std::wcout << lookup();
    > >>> ------------------------------


    > >>> I would like it to fail compile time, so I can properly
    > >>> convert cases like this to unicode in a meaningful way.


    > >>> Any ideas?


    > >> Declare and do not define std::eek:perator<<(wostream&, char
    > >> const*) yourself?


    > >> namespace std
    > >> {
    > >> inline
    > >> wostream& operator<<(wostream& wos, const char*);
    > >> }


    > >> Just an idea...


    > > That's undefined behavior. You're not allowed to define new
    > > free functions in a std::.


    > I knew someone would say that...


    > But really: Who cares in this case if it just works (with some
    > modifications and only (?) with g++ (see my other post)) ?


    Does it work? It might, or it might not. Or it might work some
    of the time, and not others. There are things you can
    reasonably define in std::, and expect to get away with it. But
    this isn't one of them.

    > > The standard std::wostream defines an operator<< for char
    > > const*. You have to assume that some of the other
    > > operator<< for wostream may use it, so you really have to
    > > leave it.


    And that is why. If you declare your version of the function,
    either:

    -- The only version in the standard library is the template
    version. Your version overloads it, and since it is not a
    template, has precedence in operator overload resolution.
    If the library has overloaded the << operator for, say,
    complex with something like:

    template< typename Float, typename CharT ... >
    std::basic_ostream< CharT ... >&
    operator<<( std::basic_ostream< CharT ... >& dest,
    std::complex< Float > const& z )
    {
    dest << "(" << z.real() << "," << z.imag() << ")" ;
    return dest ;
    }

    then this function may call your version, rather than the
    standard one; which one will be chosen more or less
    randomly.

    -- If the standard library has also declared the function
    (which would seem a more or less likely "optimization" for
    the usual cases of std::eek:stream and std::wostream), then
    your declaration just duplicates the one in the standard
    library, and doesn't change anything.

    The standard limits what you can do in std:: for a very real
    reason.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Dec 12, 2007
    #8
  9. Erik Knudsen

    Pete Becker Guest

    On 2007-12-12 10:28:09 -0500, James Kanze <> said:

    > On Dec 12, 2:40 pm, Stefan Naewe <> wrote:
    >
    >> But really: Who cares in this case if it just works (with some
    >> modifications and only (?) with g++ (see my other post)) ?

    >
    > Does it work? It might, or it might not. Or it might work some
    > of the time, and not others. There are things you can
    > reasonably define in std::, and expect to get away with it. But
    > this isn't one of them.
    >


    But as a short-term debugging aid, this is fine: if it detects
    problems, you fix them. Once you've done that, you remove it. I've
    occasionally gone so far as to add #error statements to standard
    headers when I couldn't figure out why some header was being included
    in a bogus context. (One of the Windows headers pulls in <stdlib.h>
    while inside an extern "C" block. Sigh.)

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
     
    Pete Becker, Dec 12, 2007
    #9
  10. Erik Knudsen

    Erik Knudsen Guest

    Pete Becker wrote:
    >
    > But as a short-term debugging aid, this is fine: if it detects problems,
    > you fix them. Once you've done that, you remove it. I've occasionally
    > gone so far as to add #error statements to standard headers when I
    > couldn't figure out why some header was being included in a bogus
    > context. (One of the Windows headers pulls in <stdlib.h> while inside an
    > extern "C" block. Sigh.)



    I will only use it as a short term porting/debugging aid. However, I use
    VC++ 2005, and it doesn't give me the line numbers for a link error.


    Regards,
    Erik Knudsen
     
    Erik Knudsen, Dec 13, 2007
    #10
  11. Erik Knudsen

    Erik Knudsen Guest

    Ok, so far the best approach has been to comment out the std stream
    operators for char *, void * and bool from the stl include files - that
    made the compiler complain when we tried to stream a char *.

    However, I'm still looking for a nicer approach...


    Regards,
    Erik Knudsen


    Erik Knudsen wrote:
    > Hi!
    >
    > In converting applications from ansi to unicode, it is a problem that
    > the std::wcout accepts a const char * without complaining compile time.
    >
    > This compiles and runs:
    > ------------------------------
    > const char *lookup()
    > {
    > return "Hello world";
    > }
    > std::wcout << lookup();
    > ------------------------------
    >
    > I would like it to fail compile time, so I can properly convert cases
    > like this to unicode in a meaningful way.
    >
    > Any ideas?
    >
    >
    > Regards,
    > Erik Knudsen
     
    Erik Knudsen, Dec 14, 2007
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. lovecreatesbeauty
    Replies:
    1
    Views:
    1,071
    Ian Collins
    May 9, 2006
  2. jalkadir

    wcout' is not a member of `std'

    jalkadir, Oct 7, 2005, in forum: C++
    Replies:
    7
    Views:
    3,128
    Klaus-Georg Adams
    Oct 10, 2005
  3. Ralf Goertz

    mixing of std::cout and std::wcout

    Ralf Goertz, Jul 4, 2007, in forum: C++
    Replies:
    2
    Views:
    439
    Ralf Goertz
    Jul 6, 2007
  4. Javier
    Replies:
    2
    Views:
    574
    James Kanze
    Sep 4, 2007
  5. Replies:
    2
    Views:
    487
Loading...

Share This Page