The bizarre world of typeof()

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Mon Oct 26 07:11:35 PDT 2009


Don wrote:
> Lars T. Kyllingstad wrote:
>> Don wrote:
>>> I'm trying to make sense of the rules for 'typeof'. It's difficult 
>>> because DMD's behaviour is so different to the spec. Here's four 
>>> simple cases.
>>>
>>> // This doesn't compile on D1.
>>> //alias typeof(int*int) Alias1;
>>>
>>> // This compiles in D1, but not in D2.
>>> alias int Int;
>>> alias typeof(Int*Int) Alias2;
>>>
>>> // Yet this DOES compile on D2 !
>>> typeof(T*U) foo(T, U)(T x, U y) { return x*y; }
>>> alias typeof(foo(Int, Int)) Alias3;
>>>
>>> // And this fails on both D1 and D2, with a dreadful error message.
>>> //alias typeof(foo(int)) Alias4;
>>>
>>> I can't see anything in the spec to say why ANY of these examples 
>>> should compile. Yet, the existing template constraints features 
>>> relies on the Alias3 case.
>>
>>
>> Here are a few more:
>>
>>     class Foo { real bar() { return 1.0; } }
>>     Foo foo = new Foo;
>>
>>     // Passes, but should fail.
>>     static assert (is (typeof(foo.bar) == function));
>>
>>     // Passes, as expected.
>>     static assert (is (typeof(&foo.bar) == delegate));
>>
>>     // Passes, but should fail. This is similar to Don's examples.
>>     static assert (is (typeof(Foo.bar) == function));
>>
>>     // This one fails with the following hilarious message:
>>     // Error: static assert  (is(real function() == function)) is false
>>     static assert (is (typeof(&Foo.bar) == function));
>>
>> I have no idea why typeof(&Foo.bar) even works, but it does. &Foo is 
>> completely meaningless.
> 
> Dot has higher precedence than &, so it means &(Foo.bar), not (&Foo).bar.
> 
> The static assert fails because "real function()" is a *function 
> pointer*, but is(xxx == function) tests to see if xxx is a *function*, 
> not a *function pointer*.
> 
> So this passes:
> void function () goo;
> static assert( is (typeof(*goo) == function));
> 
> It's pretty awful that that in "is(real function() == function)", the 
> keyword 'function' has two contradictory meanings in the same 
> expression. And the spec never says what "function type" is.


Ok, I see now. It's not wrong then, just ugly. :)

   static assert (is (int delegate() == delegate));  // passes
   static assert (is (int function() == function));  // fails


What about my first example then, is that the intended behaviour as 
well? With the current property syntax, I'd expect this to work, but it 
doesn't:

   static assert (is (typeof(foo.bar) == typeof(foo.bar())));

   Error: static assert  (is(real() == real)) is false

-Lars



More information about the Digitalmars-d mailing list