Function pointers/delegates default args were stealth removed?

Carl Sturtivant sturtivant at gmail.com
Wed Aug 29 02:25:19 PDT 2012


On Tuesday, 28 August 2012 at 23:34:54 UTC, Carl Sturtivant wrote:
> On Tuesday, 28 August 2012 at 21:40:01 UTC, Timon Gehr wrote:
>> On 08/28/2012 10:33 PM, Carl Sturtivant wrote:
>>> On Monday, 27 August 2012 at 00:44:54 UTC, Walter Bright 
>>> wrote:
>>>> On 8/26/2012 4:50 PM, Timon Gehr wrote:
>>>>> On 08/27/2012 12:41 AM, Walter Bright wrote:
>>>>>>
>>>>>> The trouble for function pointers, is that any default 
>>>>>> args would need
>>>>>> to be part of the type, not the declaration.
>>>>>>
>>>>>
>>>>> They could be made part of the variable declaration.
>>>>
>>>> You mean part of the function pointer variable?
>>>>
>>>> Consider what you do with a function pointer - you pass it 
>>>> to someone
>>>> else. That someone else gets it as a type, not a 
>>>> declaration. I.e. you
>>>> lose the default argument information, since that is not 
>>>> attached to
>>>> the type.
>>>
>>> I think this is the right behavior too. Default arguments are 
>>> IMHO just
>>> a compact way to write some simply related overloaded 
>>> functions, e.g. thus:
>>>
>>>  int sum(int x, int y = 1 ) { return x + y; }
>>>
>>> is just a compact way to write
>>>
>>>  int sum(int x, int y) { return x + y; }
>>>  int sum(int x) { return sum(x, 1); }
>>> ...
>>
>> This interpretation is simply wrong.
>>
>> import std.stdio, std.c.stdlib;
>>
>> void* alloca20bytes(void* x = alloca(20)){ return x; }
>>
>> // your suggested transformation:
>>
>> /+void* alloca20bytes(void* x){ return x; }
>> void* alloca20bytes(){ return alloca20bytes(alloca(20)); }+/
>>
>> // would break the caller:
>>
>> void main(){
>>    auto x = (cast(int*)alloca20bytes())[0..5];
>>    x[] = 0;
>>    x[] += 2;
>>    writeln(x);
>> }
>
> Function inlining or not in the presence of alloca calls and 
> similar using the existing stack frame are problematic. If the 
> first call was inlined by the compiler, that would un-break the 
> "problem". I suggest that we simply define default arguments 
> via the transformation I suggested, and regard
>   void* alloca20bytes(void* x = alloca(20)){ return x; }
> as broken. It's not compelling for a lot of reasons.
>
> Of course there may be something else wrong with the 
> transformation! Fire away.

Another, more conservative, approach would be for the compiler to 
regard the non-general functions in such a group created by my 
transformation to be always inlined, so the default parameters 
are always evaluated before the call. Then your interesting 
example would work the way you expect.




More information about the Digitalmars-d mailing list