Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constructor aliasing fails #2

Open
blm768 opened this issue Aug 24, 2013 · 12 comments
Open

Constructor aliasing fails #2

blm768 opened this issue Aug 24, 2013 · 12 comments

Comments

@blm768
Copy link
Owner

blm768 commented Aug 24, 2013

Mixing in multiple constructors and aliasing them together makes DMD complain that the constructors are not accessible.

@vuaru
Copy link
Contributor

vuaru commented Sep 23, 2013

I found a hilariously old thread about this: http://forum.dlang.org/thread/fv7r3g$3ub$1@digitalmars.com

Seems the problem is this: http://dlang.org/struct.html#StructLiteral

If a struct has a member function named opCall, then struct literals for that struct are not possible.

...
Actually, after reading a bit more I came across this: http://dlang.org/operatoroverloading.html#FunctionCall

To avoid the limitation, you need to also declare constructor so that it takes priority over opCall in Type(...) syntax.

Which you seem to do. Huh, weird.

Anyway, changing the test.d to not use struct literals makes at least btVector3 work.
btQuaternion still complains:

Error: struct btQuaternion does not overload ()

quaternion.d's mixin(joinOverloads!.. doesn't actually mixin anything?

@blm768
Copy link
Owner Author

blm768 commented Sep 23, 2013

I had replaced all of the constructors with static opCall because I was
having issues overloading them, so currently there shouldn't be any true
constructors for those structs. As for joinOverloads, you're right about
it not mixing anything in; I never finished implementing it.

At this point, I think that D might not be ready to create a binding
like this using only compile-time code generation. The bindings may need
to move to using an external generator. I've started working on an
interface description language using the Pegged parser generator; I can
generate the C++ and D sides of the bindings from that, which means that
I won't need to use any mixins. That should sidestep the overloading
issues with the constructors.

On 09/23/13 05:24, vuaru wrote:

I found a hilariously old thread about this:
http://forum.dlang.org/thread/fv7r3g$3ub$1@digitalmars.com
http://forum.dlang.org/thread/fv7r3g%243ub%241@digitalmars.com

Seems the problem is this: http://dlang.org/struct.html#StructLiteral

If a struct has a member function named opCall, then struct
literals for that struct are not possible.

...
Actually, after reading a bit more I came across this:
http://dlang.org/operatoroverloading.html#FunctionCall

To avoid the limitation, you need to also declare constructor so
that it takes priority over opCall in Type(...) syntax.

Which you seem to do. Huh, weird.

Anyway, changing the test.d to not use struct literals makes at least
btVector3 work.
btQuaternion still complains:

Error: struct btQuaternion does not overload ()

quaternion.d's mixin(joinOverloads!.. doesn't actually mixin anything?


Reply to this email directly or view it on GitHub
#2 (comment).

@vuaru
Copy link
Contributor

vuaru commented Sep 23, 2013

I had replaced all of the constructors with static opCall because I was having issues overloading them, so currently there shouldn't be any true constructors for those structs.

Oh so you do have only opCalls defined, and no constructors. Then it makes sense that they cannot be used as struct literals in test.d, since that's what the link explicitly states.

It's a limitation, sure, but if that's the only problem left..

@blm768
Copy link
Owner Author

blm768 commented Sep 23, 2013

On 09/23/13 12:35, vuaru wrote:

Oh so you do have only opCalls defined, and no constructors. Then it
makes sense that they cannot be used as struct literals in test.d,
since that's what the link explicitly states.

It's a limitation, sure, but if that's the only problem left..


Reply to this email directly or view it on GitHub
#2 (comment).

The problem is that I'm not sure how to get around that particular
issue. If I define constructors, it looks like they'll be used instead
of static opCall, but trying to overload the constructors has just given
me issues so far. If I throw in dummy constructors, the compiler starts
complaining that the static method cppNew is not accessible. I'll play
with it a bit more, but I'm not optimistic that I can actually get a
stable solution.

@vuaru
Copy link
Contributor

vuaru commented Sep 24, 2013

trying to overload the constructors has just given me issues so far.

What were these issues specifically?

@blm768
Copy link
Owner Author

blm768 commented Sep 24, 2013

On 09/24/13 08:03, vuaru wrote:

trying to overload the constructors has just given me issues so far.

What were these issues specifically?

I can't remember exactly what error messages DMD gave me, but I remember
that DMD choked on this particular style of code:

struct SomeBindingClass {
//...

 mixin constructor!() _c0;
 alias _c0.__ctor __ctor;
 mixin constructor!(int) _c1;
 alias _c1.__ctor __ctor;

}

The constructors have to be aliased together for overloading to work on
them, but there seems to be no way to refer to the constructor other
than through the __ctor identifier. However, DMD doesn't seem to accept
that as a callable constructor because it wasn't defined using the
"this() {}" syntax outside of the mixin. As far as I can tell, the only
way around the issue is to convert the constructor mixin to a string
mixin, but then it doesn't have access to typeof(this) unless I pass it
as an explicit parameter, which I'm trying to avoid if at all possible.

@vuaru
Copy link
Contributor

vuaru commented Sep 24, 2013

If I understand correctly, then you're saying you can't use the template mixins to insert multiple overloading contructors?

Either that is no longer the case or I'm misunderstanding, because I just tried the following simplified example which compiles:

import std.stdio;

void main()
{
    writeln(Tree(4).apple);
    writeln(Tree(4,3).apple);
    writeln(Tree(4,3,2).apple);
}

struct Tree
{
    int apple;

    mixin test;
}

mixin template test()
{
    this(int i) { apple = i; }
    this(int i, int j) { apple = i+j; }
    this(int i, int j, int k) { apple = i+j+k; }
}

(Note: I'm interested in making a simplified version of the wished-for functionality so I can ask the newsgroups for help.)

@blm768
Copy link
Owner Author

blm768 commented Sep 24, 2013

It works when all of the overloaded constructors are in the same
template instance. However, this shouldn't compile:

|import std.stdio;

void main()
{
writeln(Tree(4).apple);
writeln(Tree(4,3).apple);
writeln(Tree(4,3,2).apple);
}

struct Tree
{
int apple;

 mixin constructor!(int);
 mixin constructor!(int, int);
 mixin constructor!(int, int, int);

}

mixin template constructor(Args)
{
this(Args) {/* some code here*/}
}
|

That example is much closer to the actual structure of the binding code.

On 09/24/13 11:56, vuaru wrote:

If I understand correctly, then you're saying you can't use the
template mixins to insert multiple overloading contructors?

Either that is no longer the case or I'm misunderstanding, because I
just tried the following simplified example which compiles:

|import std.stdio;

void main()
{
writeln(Tree(4).apple);
writeln(Tree(4,3).apple);
writeln(Tree(4,3,2).apple);
}

struct Tree
{
int apple;

 mixin test;

}

mixin template test()
{
this(int i) { apple = i; }
this(int i, int j) { apple = i+j; }
this(int i, int j, int k) { apple = i+j+k; }
}
|


Reply to this email directly or view it on GitHub
#2 (comment).

@vuaru
Copy link
Contributor

vuaru commented Sep 24, 2013

It does compile, assuming you meant

mixin template constructor(Args ...)

(Where does one find documentation about these kind of language features anyway?)

@blm768
Copy link
Owner Author

blm768 commented Sep 25, 2013

With the current DMD release, the code just chokes with an assertion error. Have you tested it with a development build?

@vuaru
Copy link
Contributor

vuaru commented Sep 25, 2013

You're right it does (in fact it gives an abnormal program termination) with DMD 2.063.2.

But it does compile with a fairly recent git HEAD (which I was using because that was required for bulletD anyway).

So to me it seems that the problem has been solved in DMD, just not yet released officially.

@blm768
Copy link
Owner Author

blm768 commented Sep 25, 2013

Interesting...
Based on DMD's behavior when normal methods are mixed in, I didn't expect DMD to allow constructors from different mixins to automatically overload with each other. I suppose that it makes sense because constructors have much more specific semantics than arbitrary methods do, so overloading is less likely to cause issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants