July 19, 2013
On Friday, 19 July 2013 at 17:14:10 UTC, Ali Çehreli wrote:
> On 07/19/2013 09:00 AM, evilrat wrote:
>
> > i think this is because GLFWwindow is (pre)defined as struct
> instead alias
> > void :(
>
> Further reduced:
>
> import std.concurrency;
>
> struct S;
>
> void main()
> {
>     receive((S * p){});
> }
>Error....
> Ali

i don't think this is compiler bug, it's just how it works. yet this is another thing one must remember when writing library - never use struct predefenitions(or any other forward refs).
so concluding all of this, it is clear this is a derelict library bug, and that we also need something to allow rewrite defenitions at least at module level, if nothing like this already exists.
July 19, 2013
On 07/19/2013 11:07 AM, evilrat wrote:

> i don't think this is compiler bug, it's just how it works.

But what code needs toHash and others for the struct type even though we are just passing a pointer around?

> yet this is
> another thing one must remember when writing library - never use struct
> predefenitions(or any other forward refs).
> so concluding all of this, it is clear this is a derelict library bug,

I am not convinced yet. I think it is something that std.concurrency is doing (perhaps because it relies on Variant?). Otherwise there is no problem with what derelict does. The following code compiles:

struct S;

void myReceive(void delegate (S *) func)
{
    S * p;
    func(p);
}

void main()
{
    myReceive((S * p){});
}

Ali

July 19, 2013
On Friday, 19 July 2013 at 18:25:26 UTC, Ali Çehreli wrote:
> On 07/19/2013 11:07 AM, evilrat wrote:
>
> > i don't think this is compiler bug, it's just how it works.
>
> But what code needs toHash and others for the struct type even though we are just passing a pointer around?
>
> > yet this is
> > another thing one must remember when writing library - never
> use struct
> > predefenitions(or any other forward refs).
> > so concluding all of this, it is clear this is a derelict
> library bug,
>
> I am not convinced yet. I think it is something that std.concurrency is doing (perhaps because it relies on Variant?). Otherwise there is no problem with what derelict does. The following code compiles:

maybe you are right about Variant, and yet it still not compiler bug, but phobos bug. rewriting std.variant and std.concurrency just because of forward refs is no go.
i think problem is that with a struct we can't just generate code for this methods(toHash,opCmp,etc) by comparing its address, even if it's not extern(C/C++) and not found by linker, or do we actually could?

July 19, 2013
On 07/19/2013 11:39 AM, evilrat wrote:

> i think problem is that with a struct we can't just generate code for
> this methods(toHash,opCmp,etc) by comparing its address

That would be wrong. Yes the compiler needs the definition of the struct to generate toHash, opCmp, and toString but note that there is no expression that needs S in that sample code.

The code uses a pointer to S, which happens to have trivial toHash, opCmp, and toString.

I think now I see where the problem is coming from. Note that the three "compiles" lines below do exercise toHash, opCmp, and toString on S*.

import std.stdio;

struct S;

void main()
{
    S* p0, p1;

    int[S*] arr;
    arr[p0] = 0;               // compiles
    writefln("%s", p0);        // compiles
    writeln(p0 < p1);          // compiles

    writeln(p0.toString());    // Error: struct S is forward referenced
}

However, calling toString() directly on the pointer naturally forwards the call to S and that requires the complete definition of the struct.

This seems to be a problem with any template that has to work with pointers. The following template cannot work with a pointer:

import std.stdio;

struct S;

void foo(T)(T val)
{
    writeln("%s", val.toString());    // ERROR
}

void main()
{
    S * p;
    foo(p);
}

So, the solution is to do something like the following:

import std.stdio;

struct S;

void foo(T)(T val)
{
    static if (is (T : U*, U)) {
        writefln("(%s)%s", T.stringof, val);

    } else {
        writefln("%s", val.toString());
    }
}

void main()
{
    S * p;
    foo(p);
}

And I think the following code in std/concurrency.d is the reason:

              ( Variant val )
// ...
                  throw new MessageMismatch(
                      format("Unexpected message type: expected '%s', got '%s'",
                          exp, val.type.toString()));
              } );

val.type returns a TypeInfo and it seems like there is no TypeInfo special for pointers to incomplete types. Shouldn't there be?

Ali

July 20, 2013
On Friday, 19 July 2013 at 19:05:27 UTC, Ali Çehreli wrote:
>
> This seems to be a problem with any template that has to work with pointers. The following template cannot work with a pointer:
> ...
>
> val.type returns a TypeInfo and it seems like there is no TypeInfo special for pointers to incomplete types. Shouldn't there be?
>
> Ali

maybe it should. but it doesn't matters what i think about how it should be, i just hope D would be user friendly, and current situation with that making it quite not so friendly.
1 2
Next ›   Last »