method static-ness has no effect on the type?

2016-08-08 Thread Cauterite via Digitalmars-d-learn

See: https://dpaste.dzfl.pl/2ec6780d4b25

We have two methods defined, f1 and f2, where f2 is static but 
they have otherwise identical signatures.
We can see from the disassembly that f1 receives a `this` pointer 
while f2 does not.
Yet, typeof(&f1) == typeof(&f2). This makes no sense, how can the 
compiler even know whether to pass a `this` pointer when both 
methods have same type?


Re: method static-ness has no effect on the type?

2016-08-08 Thread ag0aep6g via Digitalmars-d-learn

On 08/08/2016 10:30 AM, Cauterite wrote:

See: https://dpaste.dzfl.pl/2ec6780d4b25


That code is short enough to post it here directly. For easier 
reference, this is it:



struct S {

void f1() {
auto x = &this;
};

static void f2() {
static assert(!__traits(compiles, {auto x = &this;}));
};
};

static assert(is(typeof(S.f1) == typeof(S.f2))); // ?
static assert(is(typeof(&S.f1) == typeof(&S.f2)));  // ?

static assert(!__traits(isStaticFunction, S.f1));
static assert(__traits(isStaticFunction, S.f2));

void main() {

// call f2;
S.init.f2();

// mov [ebp-4], S.init;
// lea eax, [ebp-4];
// call f1;
S.init.f1();
};


(Aside: no semicolons after function/struct declarations in D.)


We have two methods defined, f1 and f2, where f2 is static but they have
otherwise identical signatures.
We can see from the disassembly that f1 receives a `this` pointer while
f2 does not.
Yet, typeof(&f1) == typeof(&f2). This makes no sense, how can the
compiler even know whether to pass a `this` pointer when both methods
have same type?


The first assert compares the return types of f1 and f2. They both 
return `void`, so everything's fine there.


The second assert is a bit more surprising. `&S.f1` is considered a 
function, but `&S.init.f1` is a delegate. Obviously, you can't get a 
proper delegate from just the type. You need an instance of the struct 
for that. So having `&S.f1` be a delegate would be weird, too.


I don't know why `&S.f1` is allowed at all. Maybe there is a good 
reason, but it also allows bad stuff like this:



struct S
{
void f1(int x) { import std.stdio; writeln(x); }
}

void main()
{
void function(int x) f = &S.f1;
f(42); /* prints garbage */
}


This even works in @safe code. It also works when using .funcptr to get 
the function pointer from a delegate. I'v filed an issue:

https://issues.dlang.org/show_bug.cgi?id=16365


Re: method static-ness has no effect on the type?

2016-08-08 Thread Cauterite via Digitalmars-d-learn

On Monday, 8 August 2016 at 10:05:58 UTC, ag0aep6g wrote:
The first assert compares the return types of f1 and f2. They 
both return `void`, so everything's fine there.


I think you're mistaken about this. typeof(S.f1) definitely gives 
the type of the function, not of the return. Try it out:


struct S {
void f1(int, string, float) {};
};
static assert(typeof(S.f1).stringof == "void(int, string, 
float)");


( https://dpaste.dzfl.pl/cda66002120a )


Re: method static-ness has no effect on the type?

2016-08-08 Thread ag0aep6g via Digitalmars-d-learn

On 08/08/2016 12:14 PM, Cauterite wrote:

On Monday, 8 August 2016 at 10:05:58 UTC, ag0aep6g wrote:

The first assert compares the return types of f1 and f2. They both
return `void`, so everything's fine there.


I think you're mistaken about this. typeof(S.f1) definitely gives the
type of the function, not of the return. Try it out:


Yup. My mistake. It's the same as with & then.



Re: method static-ness has no effect on the type?

2016-08-08 Thread Cauterite via Digitalmars-d-learn

On Monday, 8 August 2016 at 10:21:47 UTC, ag0aep6g wrote:




Also thanks for submitting the bug for me.