Simple C++ that just fails to do what it is supposed to

Discussion in 'C++' started by Michael Goldshteyn, Jan 16, 2007.

  1. Consider the following two lines of code, the first intended to print "Hello
    world\n" and the second intended to print the character 'P' to stdout.

    ---
    std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    "Hello world\n").str();

    std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    'P').str();
    ---

    Instead, the first line print the address of the string literal "Hello
    world\n" and the second prints the ASCII value of 'P', 80.

    I would like a meaningful discussion as to why this is happening. It appears
    that in the first case, the const char * that is the string literal is being
    interpreted in void * context and in the second case, the character is
    somehow being interpreted as an int.

    Thanks,

    Mike
     
    Michael Goldshteyn, Jan 16, 2007
    #1
    1. Advertising

  2. * Michael Goldshteyn:
    > Consider the following two lines of code, the first intended to print "Hello
    > world\n" and the second intended to print the character 'P' to stdout.
    >
    > ---
    > std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    > "Hello world\n").str();
    >
    > std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    > 'P').str();
    > ---
    >
    > Instead, the first line print the address of the string literal "Hello
    > world\n" and the second prints the ASCII value of 'P', 80.
    >
    > I would like a meaningful discussion as to why this is happening. It appears
    > that in the first case, the const char * that is the string literal is being
    > interpreted in void * context and in the second case, the character is
    > somehow being interpreted as an int.


    Right. std::eek:stringstream() produces a temporary. It doesn't match a
    std::eek:stringstream& parameter, so the only operations available (here)
    are the member functions, hence the member operator<<(void*) is used for
    the first example, and presumably sometthing like operator<<(int) for
    the second -- check it out if the details are of interest.

    If you really want to (but you shouldn't want that), call a member that
    returns a std::eek:stream reference, before applying << -- again, check
    it out if the details are of interest.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 16, 2007
    #2
    1. Advertising

  3. Michael Goldshteyn

    Jack Klein Guest

    On Tue, 16 Jan 2007 12:27:24 -0600, "Michael Goldshteyn"
    <> wrote in comp.lang.c++:

    > Consider the following two lines of code, the first intended to print "Hello
    > world\n" and the second intended to print the character 'P' to stdout.
    >
    > ---
    > std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    > "Hello world\n").str();
    >
    > std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    > 'P').str();
    > ---
    >
    > Instead, the first line print the address of the string literal "Hello
    > world\n" and the second prints the ASCII value of 'P', 80.
    >
    > I would like a meaningful discussion as to why this is happening. It appears


    What do you consider to be a meaningful discussion? How about the
    fact that the code does exactly what it is supposed to do, according
    to the C++ standard, and your expectations are wrong?

    > that in the first case, the const char * that is the string literal is being
    > interpreted in void * context and in the second case, the character is
    > somehow being interpreted as an int.


    The insertion operator (<<) for streams is overloaded for all the
    built-in types. Its purpose is to generate text streams, so for all
    integer and floating point arithmetic types it performs a numeric
    value to text conversion and inserts the text into the stream.

    Type char is a character type, so this numeric value to text
    conversion is performed, exactly as the standard requires it to be. In
    your character set, probably ASCII, the numeric value of 'P' is 80.

    There is a special overload for pointer to character types. This
    overload is based on the assumption that they are pointing to C style
    strings (arrays of characters terminated by a '\0' character). Such
    strings are already text, so no conversion is necessary, the C string
    is merely inserted into the stream as-is.

    On the relatively rare occasions when you actually what to output a
    text representation of the address contained in a pointer to char,
    rather than the C string it is assumed to point to, you merely cast it
    to pointer to void, which has no such overload.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jan 16, 2007
    #3
  4. "Jack Klein" <> wrote in message
    news:...
    > On Tue, 16 Jan 2007 12:27:24 -0600, "Michael Goldshteyn"
    > <> wrote in comp.lang.c++:
    >
    >> Consider the following two lines of code, the first intended to print
    >> "Hello
    >> world\n" and the second intended to print the character 'P' to stdout.
    >>
    >> ---
    >> std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    >> "Hello world\n").str();
    >>
    >> std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    >> 'P').str();
    >> ---
    >>
    >> Instead, the first line print the address of the string literal "Hello
    >> world\n" and the second prints the ASCII value of 'P', 80.
    >>
    >> I would like a meaningful discussion as to why this is happening. It
    >> appears

    >
    > What do you consider to be a meaningful discussion? How about the
    > fact that the code does exactly what it is supposed to do, according
    > to the C++ standard, and your expectations are wrong?
    >
    >> that in the first case, the const char * that is the string literal is
    >> being
    >> interpreted in void * context and in the second case, the character is
    >> somehow being interpreted as an int.

    >
    > The insertion operator (<<) for streams is overloaded for all the
    > built-in types. Its purpose is to generate text streams, so for all
    > integer and floating point arithmetic types it performs a numeric
    > value to text conversion and inserts the text into the stream.
    >
    > Type char is a character type, so this numeric value to text
    > conversion is performed, exactly as the standard requires it to be. In
    > your character set, probably ASCII, the numeric value of 'P' is 80.
    >
    > There is a special overload for pointer to character types. This
    > overload is based on the assumption that they are pointing to C style
    > strings (arrays of characters terminated by a '\0' character). Such
    > strings are already text, so no conversion is necessary, the C string
    > is merely inserted into the stream as-is.
    >
    > On the relatively rare occasions when you actually what to output a
    > text representation of the address contained in a pointer to char,
    > rather than the C string it is assumed to point to, you merely cast it
    > to pointer to void, which has no such overload.


    Either you misunderstood my argument or I am not understanding your reply. I
    was expecting the string and the character to be outputted and got their
    address and ASCII value, respectively, instead.

    Mike
     
    Michael Goldshteyn, Jan 16, 2007
    #4
  5. "Alf P. Steinbach" <> wrote in message
    news:...
    >* Michael Goldshteyn:
    >> Consider the following two lines of code, the first intended to print
    >> "Hello world\n" and the second intended to print the character 'P' to
    >> stdout.
    >>
    >> ---
    >> std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    >> "Hello world\n").str();
    >>
    >> std::cout << static_cast<std::eek:stringstream &>(std::eek:stringstream() <<
    >> 'P').str();
    >> ---
    >>
    >> Instead, the first line print the address of the string literal "Hello
    >> world\n" and the second prints the ASCII value of 'P', 80.
    >>
    >> I would like a meaningful discussion as to why this is happening. It
    >> appears that in the first case, the const char * that is the string
    >> literal is being interpreted in void * context and in the second case,
    >> the character is somehow being interpreted as an int.

    >
    > Right. std::eek:stringstream() produces a temporary. It doesn't match a
    > std::eek:stringstream& parameter, so the only operations available (here) are
    > the member functions, hence the member operator<<(void*) is used for the
    > first example, and presumably sometthing like operator<<(int) for the
    > second -- check it out if the details are of interest.
    >
    > If you really want to (but you shouldn't want that), call a member that
    > returns a std::eek:stream reference, before applying << -- again, check it
    > out if the details are of interest.


    I understand your reply. I do not, however, understand the logic of having
    overloaded operator<< member functions for void * and int, and not for all
    of the other built in types. There should have been no such functions, as
    members of the ostringstream class, or all of them should have been included
    (i.e. for all of the built-in types), as is the case for non-member
    operator<< functions that work with an ostringstream reference.

    Mike
     
    Michael Goldshteyn, Jan 16, 2007
    #5
  6. Michael Goldshteyn wrote:
    > [..] I do not, however, understand the logic of
    > having overloaded operator<< member functions for void * and int, and
    > not for all of the other built in types. There should have been no
    > such functions, as members of the ostringstream class, or all of them
    > should have been included (i.e. for all of the built-in types), as is
    > the case for non-member operator<< functions that work with an
    > ostringstream reference.


    That's a very valid concern. Posting it to 'comp.std.c++' can help
    clear it up. Ask for *rationale* behind that decision. We here mostly
    discuss "how", very rarely "why". They there have the "why" answers.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 16, 2007
    #6
    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. ThunderMusic

    How I'm I supposed to use string tables?

    ThunderMusic, Oct 15, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    458
    John Saunders
    Oct 15, 2004
  2. Simon Harvey
    Replies:
    5
    Views:
    453
    Scott M.
    Nov 16, 2003
  3. Jan Nielsen
    Replies:
    7
    Views:
    536
    Jan Nielsen
    Feb 8, 2005
  4. Replies:
    3
    Views:
    1,521
  5. Rob Somers

    fgets() - supposed to be simple :)

    Rob Somers, Nov 23, 2003, in forum: C Programming
    Replies:
    5
    Views:
    577
    Peter Shaggy Haywood
    Nov 25, 2003
Loading...

Share This Page