Thread overview
Imcompatible type, const and const
Mar 09, 2014
Duarte
Mar 09, 2014
bearophile
Mar 09, 2014
Duarte
Mar 09, 2014
Duarte
Mar 09, 2014
bearophile
Mar 10, 2014
Mike Parker
March 09, 2014
Hi guys,
While I was out there, trying some D and stuff, I came with an error message I can't understand.

Let's assume I have something like:

class Point2
{
    Vector2 opBinary(string op)(const Point2 _right)
    {
        static if(op == "-")
        {
            return new Vector2(   this.x - _right.x,
                                  this.y - _right.y   );
        }
    }

    public static float DistanceSq(const Point2 _left, const Point2 _right)
    {
        return _left.DistanceSq(_right);
    }

    public float Distance(const Point2 _right) const
    {
        Vector2 vec = this - _right;
        [...]
    }
}

The line "Vector2 vec = this - _right" is giving me the following error:
Error: incompatible types for ((this) - (_right)): 'const(Point2)' and 'const(Point2)'

What am I missing here? The same code in C++ compile, so I was assuming it would just as well compile in D.

Cheers!
March 09, 2014
Duarte:

> What am I missing here? The same code in C++ compile, so I was assuming it would just as well compile in D.

C++ and D are two different languages, and among other things they have two very different constant-ness systems, so code in one language often can't work in the other.

In your code probably there are multiple problems. One problem I see is here:

    Vector2 opBinary(string op)(const Point2 _right) {
        static if(op == "-") {
            return new Vector2(this.x - _right.x, this.y - _right.y);
        }
    }

You have to use a template constraint otherwise one of your code paths returns nothing, and this is (thankfully) an error in D.

Also regarding your style, in D functions start with a lower case letter.

I suggest to ask similar questions in the D.learn newsgroup.

Bye,
bearophile
March 09, 2014
I don't know how I ended up in D.ide...

I did not copy all the code, because it didn't matter in this case. The path that returns nothing is actually a:
static if(op == "-")
{
    ...
}
else
{
    static assert(...)
}

Which hopefully won't compile if the operation is not supported.
March 09, 2014
On Sunday, 9 March 2014 at 16:56:52 UTC, Duarte wrote:
> I don't know how I ended up in D.ide...
>
> I did not copy all the code, because it didn't matter in this case. The path that returns nothing is actually a:
> static if(op == "-")
> {
>     ...
> }
> else
> {
>     static assert(...)
> }
>
> Which hopefully won't compile if the operation is not supported.

Hmm
Vector2 vec = cast(Point2)this - cast(Point2)_right
does the trick. But I can't help to feel this is a ugly hack/workaround to a problem elsewhere...
March 09, 2014
Duarte:

> Hmm
> Vector2 vec = cast(Point2)this - cast(Point2)_right
> does the trick. But I can't help to feel this is a ugly hack/workaround to a problem elsewhere...

In your code you don't have this problem, but in D, unlike C++, mutating const/immutable data is undefined, and leading to unpredictable but frequent bugs.

Bye,
bearophile
March 10, 2014
On 3/10/2014 1:15 AM, Duarte wrote:
> Hi guys,
> While I was out there, trying some D and stuff, I came with an error
> message I can't understand.
>
> Let's assume I have something like:
>
> class Point2
> {
>      Vector2 opBinary(string op)(const Point2 _right)
>      {
>          static if(op == "-")
>          {
>              return new Vector2(   this.x - _right.x,
>                                    this.y - _right.y   );
>          }
>      }
>
>      public static float DistanceSq(const Point2 _left, const Point2
> _right)
>      {
>          return _left.DistanceSq(_right);
>      }
>
>      public float Distance(const Point2 _right) const
>      {
>          Vector2 vec = this - _right;
>          [...]
>      }
> }
>
> The line "Vector2 vec = this - _right" is giving me the following error:
> Error: incompatible types for ((this) - (_right)): 'const(Point2)' and
> 'const(Point2)'
>
> What am I missing here? The same code in C++ compile, so I was assuming
> it would just as well compile in D.
>
> Cheers!

I'm assuming that the error is occurring when you call the static DistanceSq. What's happening is that the static method takes two const Points. The call to _left.DistanceSq means that the this object for that call (_left) is const. That call passes because DistanceSq (which I assume you've mistyped as Distance here) is declared as a const method. The problem, though, is that your opBinary is not a const method so it cannot work on const(this) object -- const(this) - const(_right) is what you have. If you make opBinary a const method, you won't see this error anymore.

Also, it's probably a better idea to use structs for object types like vectors and points. D's GC isn't state of the art, so something as frequently allocated as points and vectors will likely cause issues.