The bizarre world of typeof()

grauzone none at example.net
Mon Oct 26 08:08:21 PDT 2009


Lars T. Kyllingstad wrote:
> grauzone wrote:
>> Lars T. Kyllingstad wrote:
>>> Kagamin wrote:
>>>> Lars T. Kyllingstad Wrote:
>>>>
>>>>>      // This one fails with the following hilarious message:
>>>>>      // Error: static assert  (is(real function() == function)) is 
>>>>> false
>>>>>      static assert (is (typeof(&Foo.bar) == function));
>>>>
>>>> Failure is valid, compiler just can't show member function types 
>>>> correctly.
>>>
>>>
>>> I'm not saying it should compile, I'm saying that the compiler should 
>>> give an error when it encounters the expression &Foo.bar, and not 
>>> just because of the failed assertion. It's bad enough that it accepts 
>>> Foo.bar (this is what Don was talking about), but allowing one to 
>>> take the address as well is just nonsense -- even when it's in an 
>>> is(typeof()) expression.
>>>
>>> In fact, &Foo.bar actually returns an address. The following compiles:
>>>
>>>     class Foo { real bar() { return 1.0; } }
>>>     auto f = &Foo.bar;
>>>     auto x = f();
>>>
>>> Of course, when run, it segfaults on the last line. I wonder where f 
>>> actually points to.
>>
>> We need that to get the address of a function. It's just that the type 
>> of the returned object is a bit bogus: it's not really a function; 
>> it's a method pointer casted to a function pointer. It simply has the 
>> wrong calling convention.
> 
> Ok, thanks for explaining. Are there cases where it's useful to have a 
> pointer to a member function without its context?

You could use it to dynamically build a delegate to that function. Or to 
allow serialization of delegates. Maybe there are other uses as well. 
Anyway, you really shouldn't have to instantiate a class just to get 
method addresses.

> 
>> We also need typeof(&Foo.bar) to get the parameter and return types 
>> for the bar method.
> 
> Good point.
> 
> -Lars



More information about the Digitalmars-d mailing list