473,832 Members | 2,309 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this a compiler bug?

Hi,

I have some weird compiler behaviour, so I'm hoping that one of the gurus
here will be able to tell me whether or not it really is a compiler bug.

In short, the compiler is saying that it cannot choose between two
overloaded versions of a method when, IMHO, one overload is clearly a
"better" choice than the other. I've looked through all the rules for
overload resolution, and I can't see any justification for the compiler's
error message.

I'll include a stripped down demonstration of the "bug" below. But first, a
"disclaimer ": yes, I have included an implict conversion operator on one of
the classes and yes, the problem does go away if I remove it. However,
regardless of the fact that I've included it, I still believe the compiler is
wrong about the ambiguity.

What do you think?

Here's the code:

public class A
{
public static implicit operator B(A a)
{
return new B(); //actual implementation omitted
}
}

public class B
{
}

public class ShowError
{
public static void Method(A a, B b)
{ }

public static void Method(B b, A a)
{ }

public static void ThisFailsToComp ile()
{
A a = new A();
Method(a, null);
//Compiler says this call is ambiguous, BUT
//Surely Method(A a, B b) is better than Method(B b, A a)
//since the former requires NO implicit conversion of the first
param
}

}

John

Dec 27 '05
18 1386

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Mike Schilling <ms************ *@hotmail.com> wrote:
> Exactly. I can't see why it's there, at the moment. No doubt it'll all
> make sense with a bit of explanation.


Perhaps. The oddities that result from discarding overrides before
finding
the best match don't seem to make much sense. (http://tinyurl.com/ckd8e,
if
it's been too long.)


Don't worry - that was one of the first things I commented on :)

(And it's surprised everyone I've shown it to so far...)


I have a writeup on it, including an example and suggestions for addressing
it. It didn't motivate the Microsoft folks I gave it to, but you're welcome
to it, if you'd like.
Dec 28 '05 #11
Mike Schilling <ms************ *@hotmail.com> wrote:
Don't worry - that was one of the first things I commented on :)

(And it's surprised everyone I've shown it to so far...)


I have a writeup on it, including an example and suggestions for addressing
it. It didn't motivate the Microsoft folks I gave it to, but you're welcome
to it, if you'd like.


Unfortunately, I can't see a way of fixing it at this point - if
existing apps rely on the current overloading rules, changing the rules
would break those apps.

I'm hoping that it'll at least be recognised as a flaw in future
versions...

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 28 '05 #12

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Mike Schilling <ms************ *@hotmail.com> wrote:
> Don't worry - that was one of the first things I commented on :)
>
> (And it's surprised everyone I've shown it to so far...)


I have a writeup on it, including an example and suggestions for
addressing
it. It didn't motivate the Microsoft folks I gave it to, but you're
welcome
to it, if you'd like.


Unfortunately, I can't see a way of fixing it at this point - if
existing apps rely on the current overloading rules, changing the rules
would break those apps.


It's not possible to make the compiler choose a different overload, but it
is possible to have the problematical cases cause a compilation error.
(That is, fix the overload rules, and consider any situation where new and
old rules would choose different ones "problematical" ) Since the bad
behavior is the compiler choosing the wrong overload, not runtime dispatch
to the wrong override, there is no change to the behavior of binaries.
And it would need to be fixed gradually, over a few versions (silence
becomes warning becomes error, with a flag at each stage to escalate
warnings to errors, or vice versa.)

Dec 28 '05 #13
> Exactly. I can't see why it's there, at the moment. No doubt it'll all
make sense with a bit of explanation.


Thinking about it over the past day or so, I've concluded that the rule
(about one-way implicit conversions) is there because its a clever way to
"kill two birds with one stone". Perhaps you've thought of this too, so I'd
be interested in whether you think MS were wrong to take this approach, or
whether this explaination fails to adequately explain their decision.

Here's how it kills two birds with one store. Consider two specific cases:

Case A, subclasses:

void Method(object o)
void Method(MyClass o)

if you call it with something that has a compile-time type of MyClass, it
will call the second version. (Exactly _why_ you'd write code like this, I
don't know, since it depends on the compile-time type not the run-time type,
which is icky. But anyway, it ties in with the next case....)

Case B, numeric types:

void Method(double d)
void Method(int i)

if you call it with an int, it should choose the second one - and it will
because int is convertable to double but not vice versa.

Why is this similar to the first case? Because, in the first case, MyClass
"is a" object. In the second case, in some sense, an int "is a" double.
I.e. the one-way-conversion rule generalizes the usual "is a" semantics of
inheritance, to apply them in a more general sense. If X is implicity
convertable to Y, then in a sense any X "is a" Y.

In all cases, the rule picks the most specific override - i.e. the class at
the bottom of the tree of "is a" relationships. I.e. it picks int instead of
double, and MyClass instead of object.

Anyway, that's the only rationale that I've been able to think of, for the
rule.

As for the other issue mentioned elsewhere in this thread - in which C#
picks the wrong method due to where the various versions where defined in the
class heirarchy - that's _got_ to be a compiler bug, surely!

Dec 29 '05 #14

"John Rusk" <Jo******@discu ssions.microsof t.com> wrote in message
news:BF******** *************** ***********@mic rosoft.com...

As for the other issue mentioned elsewhere in this thread - in which C#
picks the wrong method due to where the various versions where defined in
the
class heirarchy - that's _got_ to be a compiler bug, surely!


No, it's strictly according to the spec. See the thread I referenced (via
tinyurl) for the gruesome details.
Dec 29 '05 #15
class heirarchy - that's _got_ to be a compiler bug, surely!


No, it's strictly according to the spec. See the thread I referenced (via
tinyurl) for the gruesome details.


Opps, that's what I meant - more a "spec bug" than "code bug", as you and
Jon have discussed in the other thread. I can't believe that MS don't seem
to be listening to your concerns!
Dec 29 '05 #16
John Rusk <Jo******@discu ssions.microsof t.com> wrote:
Exactly. I can't see why it's there, at the moment. No doubt it'll all
make sense with a bit of explanation.


Thinking about it over the past day or so, I've concluded that the rule
(about one-way implicit conversions) is there because its a clever way to
"kill two birds with one stone". Perhaps you've thought of this too, so I'd
be interested in whether you think MS were wrong to take this approach, or
whether this explaination fails to adequately explain their decision.


<snip>

Ah, yes. I think you're right - although a better example would be:

void Method(object o)
void Method(MyBaseCl ass o)

and you call it with an expression of type MyDerivedClass (with the
obvious hierarchy). In the example you gave, you'd instantly run into
the rule of "if the type is exactly correct, use that one".

Now, that suggests a good transformation of your code to show what's
going on. Consider this:

public class Derived: Base
{
}

public class Base
{
}

class Example
{
static void Method(Derived a, Base b)
{
}

static void Method(Base b, Derived a)
{
}

static void Main()
{
A a = new A();
Method(a, null);
}
}

It now seems more reasonable for the compiler to complain, because null
as a Derived is more specific than null as a Base.

I'll edit my annotation appropriately.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 29 '05 #17
I'll edit my annotation appropriately.


Cool.

Did you also intend to change the first line of Main(), from using A to
using Derived?

John

PS I hope you'll also be able to find a way to encourage some
clarification/documentation of the case where there's no inheritance, just an
implicit conversion. It's probably a rarer case, but that makes it more
confusing when it does crop up.

---
John Rusk
http://www.agilekiwi.com
Dec 29 '05 #18
John Rusk <Jo******@discu ssions.microsof t.com> wrote:
I'll edit my annotation appropriately.
Cool.

Did you also intend to change the first line of Main(), from using A to
using Derived?


Yes. Fixed now, thanks :)
PS I hope you'll also be able to find a way to encourage some
clarification/documentation of the case where there's no inheritance, just an
implicit conversion. It's probably a rarer case, but that makes it more
confusing when it does crop up.


Possibly. I'll see what I can do. I'm not saying I have *any* power in
these matters, btw - all I can do is comment.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 29 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2334
by: Jeff Epler | last post by:
Hello. Recently, Generator Comprehensions were mentioned again on python-list. I have written an implementation for the compiler module. To try it out, however, you must be able to rebuild Python from source, because it also requires a change to Grammar. 1. Edit Python-2.3/Grammar/Grammar and add an alternative to the "listmaker" production: -listmaker: test ( list_for | (',' test)* )
7
3123
by: Tao Wang | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, I saw cuj's conformance roundup, but the result is quite old. I think many people like me want to know newer c++ standard conformance test result. Especially, I want to know the compiler conformance of vc7.1, vc8.0, gcc 4.x and intel c++, and also each implementation of STL. The world is moving on, right? :)
16
2860
by: pj | last post by:
(Was originally, probably wrongly, posted to the vc subgroup.) (This doesn't appear to be a c# problem, but a problem with a bug in the Visual Studio c# compiler, but, any help will be welcome...) Oh, I forgot to list the error messages; I would be delighted if someone could explain how to deduce which line number in which file is the one that the VC compiler cannot handle. Actually I'm using C#, but the only post I could find about...
0
2406
by: rollasoc | last post by:
Hi, I seem to be getting a compiler error Internal Compiler Error (0xc0000005 at address 535DB439): likely culprit is 'BIND'. An internal error has occurred in the compiler. To work around this problem, try simplifying or changing the program near the locations listed below. Locations at the top of the list are closer to the point at which the
3
5271
by: Mark Rockman | last post by:
------ Build started: Project: USDAver2, Configuration: Debug .NET ------ Preparing resources... Updating references... Performing main compilation... error CS0583: Internal Compiler Error (0xc0000005 at address 535F072A): likely culprit is 'BIND'. An internal error has occurred in the compiler. To work around this problem, try simplifying or changing the program near the locations listed below. Locations at the top of the list are...
1
1908
by: Timur Safin | last post by:
Hi All, Sorry if it is offtopic here, I wasn't able to find any more relevant group... I'm slowly approaching AMD64 build for our product (as my personal fun project). And after I ran that Amd64 cross-compiler from DDK 3790 build (proven to be good enough for my driver stuff) over the sources I've updated shortly I've found this serious assertion appearing in manyplaces of the code we have: $ tcc.ver edzunet build5105
0
1548
by: skip | last post by:
Here's a trivial little Python session which attempts to use compiler.walk (mostly unsuccessfully): % python Python 2.4.2 (#1, Feb 23 2006, 12:48:31) on sunos5 Type "help", "copyright", "credits" or "license" for more information. Module(None, Stmt(, Const('red')), Assign(, Const('blue'))])) <compiler.visitor.ExampleASTVisitor instance at 0x81f0eac>
6
2956
by: toton | last post by:
Hi, Anyone have a link to comparative study of different C++ compilers and how much they conform to C++ language standard? Most of the big platforms I know have GCC which well supports C++ standard. But mainly looking for compilers for small platforms like ARM, XScale, OMAP processors, and mobile OS's. I am not getting enough imformation which of the platforms HAVE a C++ compiler/cross compiler and how much they support C++ standard. It...
41
18246
by: Miroslaw Makowiecki | last post by:
Where can I download Comeau compiler as a trial version? Thanks in advice.
27
3083
by: Dave | last post by:
I'm having a hard time tying to build gcc 4.3.1 on Solaris using the GNU compilers. I then decided to try to use Sun's compiler. The Sun Studio 12 compiler reports the following code, which is in the source (gcc-4.3.1/gcc/c-common.c) of gcc 4.3.1, is a syntax error. I'm inclined to agree, as it is like no C I have ever met. what is "C_COMMON_FIXED_TYPES (, fract);" supposed to mean? Could it be
0
10780
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10497
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7753
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6951
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5623
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5788
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4420
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3968
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3077
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.