Web Images Videos Maps News Shopping Gmail more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Incorrect operator overload handling in .NET 2003
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  4 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Cliff  
View profile  
 More options Sep 18 2003, 5:56 pm
Newsgroups: microsoft.public.vc.stl, microsoft.public.vc.language, microsoft.public.vc
From: "Cliff" <cl...@example.com>
Date: Thu, 18 Sep 2003 21:55:29 GMT
Local: Thurs, Sep 18 2003 5:55 pm
Subject: Incorrect operator overload handling in .NET 2003
We believe we have found a compiler error in C++ .NET 2003 using the
supplied STL. In summary, the compiler incorrectly identifies the type of a
subclass and fails to invoke the correct function overload. Here is the code
that demonstrates the problem:

        #include <sstream>
        #include <iostream>
        #include <string>

        class test : public std::stringstream
        {
            public:
                void addString(const char* str);
        };

        void test::addString(const char* str)
        {
            (*this) << "Test: " << str;
        }

        int main()
        {
            test* t = new test();
            t->addString("a string");
            std::cout << t->str();
            delete t;

            return(0);
        }

When this code is run, inside the test::addString method, the stream
insertion operator is called for the string "Test:". This *should* invoke
the overload for (const char *). However, it actually invokes the overload
for (void *) causing the address of the string to be printed out instead.

If we move this functionality directly into the main function like so:

        int main()
        {
            test* t = new test();
            (*t) << "Test: " << "a string";
            std::cout << t->str();
            delete t;

            return(0);
        }

The compiler correctly identifies (const char *) as the proper overload for
the string "Test: " and the string prints out. As further evidence that
something is wrong, if the function test::addString is changed to:

        void test::addString(const char* str)
        {
            std::string theString("Test: ");
            (*this) << theString << str;
        }

The code will not compile and it displays an error that no valid method for
type std::string can be found for the insertion operator. However, the code
will compile cleanly if the same thing is placed into main like this:

        int main() {
            test* t = new test();
            std::string aString("Test: ");
            (*t) << aString << "a string";
            std::cout << t->str();
            delete t;

            return(0);
        }

The final proof that the complier is confused came when we added an explicit
cast in test::addString to give:

        void test::addString(const char* str) {
            (static_cast<std::stringstream&>(*this)) << "Test: " << str;
        }

With the cast in place, the complier properly maps "Test: " as a call to the
(const char*) overload, and requests to pass a std::string into the
insertion operator compile successfully.

Somehow, the use of (*this) inside a method of our class is not being
handled properly by the compiler. Has anyone else noticed this?

Cliff
<cliff_mccollum at hotmail dot com>


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
tom_usenet  
View profile  
 More options Sep 19 2003, 6:10 am
Newsgroups: microsoft.public.vc.stl, microsoft.public.vc.language, microsoft.public.vc
From: tom_usenet <tom_use...@hotmail.com>
Date: Fri, 19 Sep 2003 11:13:19 +0100
Local: Fri, Sep 19 2003 6:13 am
Subject: Re: Incorrect operator overload handling in .NET 2003

On Thu, 18 Sep 2003 21:55:29 GMT, "Cliff" <cl...@example.com> wrote:
>We believe we have found a compiler error in C++ .NET 2003 using the
>supplied STL. In summary, the compiler incorrectly identifies the type of a
>subclass and fails to invoke the correct function overload. Here is the code
>that demonstrates the problem:

>        #include <sstream>
>        #include <iostream>
>        #include <string>

Strictly speaking, to make it standard and portable, you need:
#include <ostream>

I agree that it should invoke the (const char*) overload, but the
reason for this is quite complex.

The problem appears to be that VC7 is failing to perform ADL properly
on the non-member operator set of a function when the member operator
exists in a base class. Here's what's meant to happen:

void test::addString(const char* str)
{
  (*this) << str;

}

The expression "(*this) << str" is an operator expression. Operator
expressions have three forms of name lookup - member operator lookup,
non-member operator lookup and built in operator lookup. Here's what
should happen for the three:

Member operator lookup:
(*this).operator<<(str) is checked. std::basic_ostream::operator<< is
found.

Non-member operator lookup:
operator<<(*this, str) is checked. Ordinary lookup finds nothing -
there are no operator<< functions at all in the global namespace.
Next, ADL is invoked. The namespace set of *this is that of itself
(the global namespace) plus that of its base classes (namespace
std)*****. The namespace set of str is empty, since it is a built-in.
So namespace std is searched for operator<<, and sure enough, some
candidate functions are found.

Built-in operator lookup:
No candidate functions are found.

The candiate functions are therefore:

All ostream::operator<< functions (including the void* one).
All std::operator<< functions so far declared (in particular, those in
<ostream> have been declared). (including the char const* one).

Obviously, std::operator<<(ostream&, char const*) is the best match,
and should be chosen unambiguously.

Now, MSVC7 only has the member ones to choose from because of the bug,
so the void* one is chosen as the best match.

In general VC7.1 has good name lookup skills (too good at times
(compared to what the standard requires) - they use fully recursive
searching of template parameter namespaces usually). However, I agree
with you that this is a bug.

Tom

***** This seems to be the mistake that MSVC7.1 is making - it isn't
searching the namespaces of base classes. This is why it works when
the cast to std::stringstream.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carl Daniel [VC++ MVP]  
View profile  
 More options Sep 19 2003, 10:32 am
Newsgroups: microsoft.public.vc.stl, microsoft.public.vc.language, microsoft.public.vc
From: "Carl Daniel [VC++ MVP]" <cpdan...@nospam.mvps.org>
Date: Fri, 19 Sep 2003 07:31:43 -0700
Local: Fri, Sep 19 2003 10:31 am
Subject: Re: Incorrect operator overload handling in .NET 2003

Cliff wrote:
> We believe we have found a compiler error in C++ .NET 2003 using the
> supplied STL. In summary, the compiler incorrectly identifies the
> type of a subclass and fails to invoke the correct function overload.

Thanks to tom (see his post) for an excellent analysis.  I agree that this
is a bug.  You can consider it reported, so it should be fixed in a future
release.

-cd


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Cliff  
View profile  
 More options Sep 22 2003, 4:42 pm
Newsgroups: microsoft.public.vc.stl, microsoft.public.vc.language, microsoft.public.vc
From: "Cliff" <cl...@example.com>
Date: Mon, 22 Sep 2003 20:42:24 GMT
Local: Mon, Sep 22 2003 4:42 pm
Subject: Re: Incorrect operator overload handling in .NET 2003
Thanks Tom and Carl. I'm glad to hear that someone else agrees with our
analysis on this one. It's also nice to know that a fix will be forthcoming.

Cliff

"Carl Daniel [VC++ MVP]" <cpdan...@nospam.mvps.org> wrote in message
news:OKBQArrfDHA.2984@TK2MSFTNGP11.phx.gbl...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google