digitalmars.D.learn - method static-ness has no effect on the type?
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?
Aug 08 2016
On 08/08/2016 10:30 AM, Cauterite wrote:See: https://dpaste.dzfl.pl/2ec6780d4b25That 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
Aug 08 2016
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 )
Aug 08 2016
On 08/08/2016 12:14 PM, Cauterite wrote:On Monday, 8 August 2016 at 10:05:58 UTC, ag0aep6g wrote:Yup. My mistake. It's the same as with & then.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:
Aug 08 2016
On Monday, 8 August 2016 at 10:21:47 UTC, ag0aep6g wrote:Also thanks for submitting the bug for me.
Aug 08 2016