Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Language Subtlety or Compiler bug?

Reply
Thread Tools

Language Subtlety or Compiler bug?

 
 
Ned Harding
Guest
Posts: n/a
 
      08-31-2004
In VC7.1 the following code outputs:
00000000
Success!

It would seem that the Y:perator<< is hiding the global operator<<
when it is outputting an object from another namespace but not when it
is outputting an object in the global namespace.

I can't help but think one of these 2 behaviors is a bug in VC7.1, but
which one?

Thanks,

Ned.




=========================================
#include <iostream>

namespace X
{
class Abc1
{
};

}
std:stream& operator<< (std:stream& strm, const X::Abc1 *node)
{
return strm << "Success!";
}

X::Abc1 * GetDoc() { return NULL; }

class Abc2
{
};

Abc2 * GetDoc2() { return NULL; }

std:stream& operator<< (std:stream& strm, const Abc2 *node)
{
return strm << "Success!";
}

namespace Y
{
std:stream & operator<<(std:stream& a, const char& b)
{
return a << "This should not run";
}

void DoTest()
{
std::cout << GetDoc() << "\n";
std::cout << GetDoc2() << "\n";
}
}



int main(int argc, char* argv[])
{
Y:oTest();
return 0;
}
 
Reply With Quote
 
 
 
 
Howard
Guest
Posts: n/a
 
      08-31-2004

"Ned Harding" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> In VC7.1 the following code outputs:
> 00000000
> Success!
>
> It would seem that the Y:perator<< is hiding the global operator<<
> when it is outputting an object from another namespace but not when it
> is outputting an object in the global namespace.
>


I don't see the operator in the Y namespace coming into play at all here.
What makes you think it is? You're not getting "This should not run" as
your output. Plus, the operator in Y uses a reference to a char, not a
pointer - of *any* type!

> =========================================
> #include <iostream>
>
> namespace X
> {
> class Abc1
> {
> };
>
> }
> std:stream& operator<< (std:stream& strm, const X::Abc1 *node)
> {
> return strm << "Success!";
> }
>
> X::Abc1 * GetDoc() { return NULL; }
>
> class Abc2
> {
> };
>
> Abc2 * GetDoc2() { return NULL; }
>
> std:stream& operator<< (std:stream& strm, const Abc2 *node)
> {
> return strm << "Success!";
> }
>
> namespace Y
> {
> std:stream & operator<<(std:stream& a, const char& b)
> {
> return a << "This should not run";
> }
>
> void DoTest()
> {
> std::cout << GetDoc() << "\n";
> std::cout << GetDoc2() << "\n";
> }
> }
>
>
>
> int main(int argc, char* argv[])
> {
> Y:oTest();
> return 0;
> }


It looks to me like your operator in the global namespace is correctly
getting called for the case where you've passing it an Abc2*. That's normal
overloading (correct?). In the case where you pass an Abc1*, however, your
code apparently isn't seeing the overloaded operator that uses an Abc1*, but
instead is calling the << normally used for a void* pointer.

I'm no expert on why that is, but if I had to guess (which I do ), I'd
say it's because there is nothing specifying that you want to use the
operator << that's in the X namespace. I'm not even sure how you would do
that. Perhaps using X:<< ?

-Howard


 
Reply With Quote
 
 
 
 
Howard
Guest
Posts: n/a
 
      08-31-2004

"Howard" <(E-Mail Removed)> wrote in message
news:sC3Zc.537788$Gx4.147573@bgtnsc04-> I'm no expert on why that is, but if
I had to guess (which I do ), I'd
> say it's because there is nothing specifying that you want to use the
> operator << that's in the X namespace. I'm not even sure how you would do
> that. Perhaps using X:<< ?
>


I meant to say "X::<<" there. (But as I said, it was just a guess. )

> -Howard
>
>



 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-31-2004
Howard wrote:
> "Howard" <(E-Mail Removed)> wrote in message
> news:sC3Zc.537788$Gx4.147573@bgtnsc04-> I'm no expert on why that is, but if
> I had to guess (which I do ), I'd
>
>>say it's because there is nothing specifying that you want to use the
>>operator << that's in the X namespace. I'm not even sure how you would do
>>that. Perhaps using X:<< ?
>>

>
>
> I meant to say "X::<<" there. (But as I said, it was just a guess. )


I think that :: is allowed only with the name. << is not a name, so it
probably should be X:perator<<. But I am just adding a guess on top
of your guess...

Victor
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      09-01-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Ned Harding) wrote:
> In VC7.1 the following code outputs:
> 00000000
> Success!
>
> It would seem that the Y:perator<< is hiding the global operator<<
> when it is outputting an object from another namespace but not when it
> is outputting an object in the global namespace.


Actually the behaviour is correct.
Also the Y:perator<< is irrelevant, the code will behave the same
without it.

[Abbreviated, equivalent code]:
> #include <iostream>
>
> namespace X { class Abc1 {} };
>
> std:stream& operator<< (std:stream& strm, const X::Abc1 *node)
> { return strm << "Success!"; }
>
> class Abc2 { };
>
> std:stream& operator<< (std:stream& strm, const Abc2 *node)
> { return strm << "Success!"; }
>
> namespace Y {
> void DoTest() {
> std::cout << (X::Abc1 *)0 << "\n";
> std::cout << (Abc2 *)0 << "\n";
> }
> }
>
> int main() {
> Y:oTest();
> }


The first example looks for:
operator<< (std:stream &, X::Abc1 *)
in the namespaces 'std' and 'X'. It finds neither.
It doesn't look in the global namespace because none of its
parameter types are in the global namespace.

However there is an implicit conversion (X::Abc1 *) --> (void *)
so it finds std:perator<<(std:stream &, void *).

The second example looks for:
operator<< (std:stream &, ::Abc2 *)
in the namespace 'std' and the global namespace. It finds
your std:stream& operator<< (std:stream& strm, const Abc2 *node)
from the global namespace.

> namespace Y {
> std:stream & operator<<(std:stream& a, const char& b)
> };


Why did you include that function? It has nothing to do with
anything else in this program because you never go
std::cout << (something with char type or convertible to char).
 
Reply With Quote
 
Ned Harding
Guest
Posts: n/a
 
      09-01-2004
(E-Mail Removed) (Old Wolf) wrote in message
> Why did you include that function? It has nothing to do with
> anything else in this program because you never go
> std::cout << (something with char type or convertible to char).


That's the weird part. If you take out Y:perator << (which I agree
never gets called) then I get

Success!
Success!

I'm not sure why y:perator << is hiding anything, but if it hides
one of the :perator<<, why doesn't it hide both?

ned.
 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      09-01-2004

"Ned Harding" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> (E-Mail Removed) (Old Wolf) wrote in message
> > Why did you include that function? It has nothing to do with
> > anything else in this program because you never go
> > std::cout << (something with char type or convertible to char).

>
> That's the weird part. If you take out Y:perator << (which I agree
> never gets called) then I get
>
> Success!
> Success!
>
> I'm not sure why y:perator << is hiding anything, but if it hides
> one of the :perator<<, why doesn't it hide both?
>
> ned.


Try moving the operator that takes the X::Abc1* parameter INSIDE the X
namespace. Then you won't have any problem.

BTW, I have no idea how it's possible to "hide" the operator like you've
described, which I've verified with all kinds of variations of that Y::
operator. But even though it's never called, it does indeed prevent VC7
from "seeing" the global namespace operator that takes a parameter type from
another namespace. But I tend not to sweat stuff like that, once I've found
a solution!

-Howard




 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      09-01-2004
(E-Mail Removed) (Ned Harding) wrote:
> (E-Mail Removed) (Old Wolf) wrote in message
> > Why did you include that function? It has nothing to do with
> > anything else in this program because you never go
> > std::cout << (something with char type or convertible to char).

>
> That's the weird part. If you take out Y:perator << (which I agree
> never gets called) then I get
>
> Success!
> Success!


I don't (gcc 3.4.1). Perhaps it is a compiler bug in MSVC.
(On BCC 5.5.1, both versions give Success! Success!, I suppose it
looks in the global namespace when it should not.. BCC is not
famous for its lack of bugs)

> I'm not sure why y:perator << is hiding anything, but if it hides
> one of the :perator<<, why doesn't it hide both?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Ruby conditionals subtlety? Farhad Farzaneh Ruby 17 02-21-2010 09:44 PM
Interesting bash subtlety Lawrence D'Oliveiro NZ Computing 6 10-27-2008 10:07 AM
writing a compiler for Monster language using C language Shravani C Programming 8 03-16-2008 09:36 PM
Can we use <compiler> tag to avoid RunTime Compiler error? Jack Wright ASP .Net 5 01-19-2004 04:36 PM
Compiler Error Message: The compiler failed with error code 128. Yan ASP .Net 0 07-21-2003 10:49 PM



Advertisments