2 bugs in VC++ 2003 
Author Message
 2 bugs in VC++ 2003

I just upgraded to .NET 2003 and I'm seeing 2 problems
that didn't happen in earlier versions.  One has an easy
workaround but the other's a real problem for me.

Trivial one:

class Z {};

class X
{
    X(unsigned int = ~0, Z* const  = 0); // doesn't compile

Quote:
};

class Y
{
    Y(unsigned int = (~0), Z* const  = 0); // this does

Quote:
};

The real problem:

class A
{
        const double (*p) [3];

public:

        A() {p = 0;}

        A(const double (&b)[3]) {p = &b;}

        A& operator = (const double (&b)[3]) {p = &b;
return *this;}

        A& operator += (const double (&b)[3]) {p = &b;
return *this;}

Quote:
};

class B
{
        double v[3];

public:

        typedef double V[3];
        operator V& () {return v;}

        // removing operator CV& fixes the error
        typedef const double CV[3];
        operator CV& () const {return v;}

Quote:
};

void test()
{
        A a;
        B b;
        a = b;  // compiler error
        a += b; // compiler error
        A c(b); // compiler error

Quote:
}

If you remove operator CV& the compiler errors go away; it
looks like there might be some confusion about ambiguities
with both const & non-const conversions.

Does anyone see an error in the code or is it really a
compiler problem?

Ron



Mon, 21 Nov 2005 02:14:25 GMT  
 2 bugs in VC++ 2003

Quote:

> Does anyone see an error in the code or is it really a
> compiler problem?

Comeau likes it.  Absent something really obscure, the code is probably
OK.

--
Craig Powers
MVP - Visual C++



Mon, 21 Nov 2005 03:06:23 GMT  
 2 bugs in VC++ 2003



Quote:
> I just upgraded to .NET 2003 and I'm seeing 2 problems
> that didn't happen in earlier versions.  One has an easy
> workaround but the other's a real problem for me.

> Trivial one:

> class Z {};

> class X
> {
>     X(unsigned int = ~0, Z* const  = 0); // doesn't compile
> };

> class Y
> {
>     Y(unsigned int = (~0), Z* const  = 0); // this does
> };

> The real problem:

> class A
> {
> const double (*p) [3];

> public:

> A() {p = 0;}

> A(const double (&b)[3]) {p = &b;}

> A& operator = (const double (&b)[3]) {p = &b;
> return *this;}

> A& operator += (const double (&b)[3]) {p = &b;
> return *this;}
> };

> class B
> {
> double v[3];

> public:

> typedef double V[3];
> operator V& () {return v;}

> // removing operator CV& fixes the error
> typedef const double CV[3];
> operator CV& () const {return v;}
> };

> void test()
> {
> A a;
> B b;
> a = b; // compiler error
> a += b; // compiler error
> A c(b); // compiler error
> }

> If you remove operator CV& the compiler errors go away; it
> looks like there might be some confusion about ambiguities
> with both const & non-const conversions.

> Does anyone see an error in the code or is it really a
> compiler problem?

I'll take a shot at the last one. :-)

The constructor for A wants a "const double...". When B has an
operator returning a reference to const double, that is the obvious
choice for a conversion, because it is a perfect fit. However, that
operator can only be used for const Bs, and b isn't const!

When you remove the best conversion, operator V&() becomes the *only*
choice. The compiler can fix a reference to const reference, as a
slight adjustement. Works OK.

To me, this looks like a bug was fixed in the compiler!

- Show quoted text -

Quote:

> Ron



Mon, 21 Nov 2005 03:24:30 GMT  
 2 bugs in VC++ 2003
Thanks Craig.  I guess I'll send in a bug report.

Ron

Quote:
>-----Original Message-----

>> Does anyone see an error in the code or is it really a
>> compiler problem?

>Comeau likes it.  Absent something really obscure, the
code is probably
>OK.

>--
>Craig Powers
>MVP - Visual C++
>.



Mon, 21 Nov 2005 05:40:11 GMT  
 2 bugs in VC++ 2003
Bo,

Quote:
>However, that
>operator can only be used for const Bs, and b isn't const!

I don't think that's right.  const methods can be called
whether the object is const or not.  const only affects
the opposite case - if the object is const, then only
const methods can be called.

Since Comeau accepts it, it's probably a new bug, not a
bug fix.

Ron

Quote:
>-----Original Message-----



>> I just upgraded to .NET 2003 and I'm seeing 2 problems
>> that didn't happen in earlier versions.  One has an easy
>> workaround but the other's a real problem for me.

>> Trivial one:

>> class Z {};

>> class X
>> {
>>     X(unsigned int = ~0, Z* const  = 0); // doesn't
compile
>> };

>> class Y
>> {
>>     Y(unsigned int = (~0), Z* const  = 0); // this does
>> };

>> The real problem:

>> class A
>> {
>> const double (*p) [3];

>> public:

>> A() {p = 0;}

>> A(const double (&b)[3]) {p = &b;}

>> A& operator = (const double (&b)[3]) {p = &b;
>> return *this;}

>> A& operator += (const double (&b)[3]) {p = &b;
>> return *this;}
>> };

>> class B
>> {
>> double v[3];

>> public:

>> typedef double V[3];
>> operator V& () {return v;}

>> // removing operator CV& fixes the error
>> typedef const double CV[3];
>> operator CV& () const {return v;}
>> };

>> void test()
>> {
>> A a;
>> B b;
>> a = b; // compiler error
>> a += b; // compiler error
>> A c(b); // compiler error
>> }

>> If you remove operator CV& the compiler errors go away;
it
>> looks like there might be some confusion about
ambiguities
>> with both const & non-const conversions.

>> Does anyone see an error in the code or is it really a
>> compiler problem?

>I'll take a shot at the last one. :-)

>The constructor for A wants a "const double...". When B
has an
>operator returning a reference to const double, that is
the obvious
>choice for a conversion, because it is a perfect fit.
However, that
>operator can only be used for const Bs, and b isn't const!

>When you remove the best conversion, operator V&()
becomes the *only*
>choice. The compiler can fix a reference to const
reference, as a
>slight adjustement. Works OK.

>To me, this looks like a bug was fixed in the compiler!

>> Ron

>.



Mon, 21 Nov 2005 05:48:39 GMT  
 2 bugs in VC++ 2003

Quote:

> Since Comeau accepts it, it's probably a new bug, not a
> bug fix.

Although Comeau is right most of the time, I think there are a couple
of cases where VC does the right thing and Comeau doesn't and a couple
more where what exactly constitutes the right thing isn't clear (and
they don't both handle it the same way).

I'm not up on the standard enough to say whether this particular case
qualifies for either -- and as I said in my other reply, this tends to
happen in the dusty corners of the standard.

--
Craig Powers
MVP - Visual C++



Mon, 21 Nov 2005 06:16:18 GMT  
 2 bugs in VC++ 2003

1st is obviously a bug.

Quote:
> The constructor for A wants a "const double...". When B has an
> operator returning a reference to const double, that is the obvious
> choice for a conversion, because it is a perfect fit. However, that
> operator can only be used for const Bs, and b isn't const!

Both are in the set of candidates since you can always call a
const member function on a nonconst instance (but no vice versa)

IMHO both operators are in the set of candidates, but
the non-const version is prefered if it is viable (and it is in
this case).

-hg



Mon, 21 Nov 2005 07:28:17 GMT  
 2 bugs in VC++ 2003
Holger,

Quote:
>IMHO both operators are in the set of candidates, but
>the non-const version is prefered if it is viable (and it
is in
>this case).

>-hg

Taking the experimental approach, VC6 & .NET 2002 both
called the non-const version.  I don't have a copy of the
standard but this makes sense to me.  I would be pretty
surprised if my test case was ambiguous under the standard
as it must be a very common idiom:  An object exposing
itself as a different data type by reference.  If it
couldn't provide both const & non-const versions it would
be crippled.

Ron



Mon, 21 Nov 2005 23:22:57 GMT  
 2 bugs in VC++ 2003

Quote:

> >IMHO both operators are in the set of candidates, but
> >the non-const version is prefered if it is viable (and it
> is in
> >this case).

> >-hg

> Taking the experimental approach, VC6 & .NET 2002 both
> called the non-const version.  I don't have a copy of the
> standard but this makes sense to me.  I would be pretty
> surprised if my test case was ambiguous under the standard
> as it must be a very common idiom:  An object exposing
> itself as a different data type by reference.  If it
> couldn't provide both const & non-const versions it would
> be crippled.

FYI 13.3.3.2/3 says:
<snip>

- Standard conversion sequence S1 is a better conversion
sequence than standard conversion sequence S2 if
[...]
S1 and S2 differ only in their qualification conversion and
yield similair types T1 and T2 (4.4), respectively, and the
cv-qualification signature of type T1 is a proper subset of
the cv-qualification of type T2, [Example:

int f(const int *);
int f(int *);
int i;
int j = f(&i);  // Calls f(int*)

-end example}
</snip>

The this pointer participates in overload resolution.

-hg



Tue, 22 Nov 2005 00:54:49 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Bug in VC++ 2003 (base class name lookup issue?)

2. Bad bug in VC++ 2003 w/ typedefs and classes.

3. Bug in VC++ 2003 Final Beta, or my mistake?

4. VC++ 2003 c2.dll bug D2029

5. VC .NET 2003 l-value bug?

6. VC++ 2003 template bug?

7. VC++ 2003 compiler bug

8. VC.NET 2003 IDE bug report

9. Very probably a bug in the code generator of VC++ 2003

10. Problem porting ATL project from VC++ 6.0 to VC++.NET 2003

11. Converting project from VC++ 2002 to VC++ 2003 and adding a new configuration

12. Slower compilation with VC Net 2003 (7.1) when compared to VC Net 7.0

 

 
Powered by phpBB® Forum Software