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); }

and a function pointer refers to a single function, so overloading and default arguments are irrelevant to function pointers. It just so happens that the particularly simple overloading abbreviated by a function definition with default arguments is easily optimized by the compiler with only one function arriving at the linker: the most general one. And that's the one whose address is supplied if the unary & operator is applied to it.

So that's the problem with 'int sum(int x, int y = 1 ) ...' --- it's not one function under the interpretation above. So how could we interpret
  int function(int x, int y = 1) sum;
in the above interpretation? What's happening right now is that sum is considered to be a single function pointer, so we discard the default to get the most general function type much like the effect of unary & above. So the trouble with the supposed type 'int function(int x, int y = 1)' is that it is not one type, just as the function sum above is not one function.

[Speculation mode starts here.] So what if function pointer declarations with defaults are considered to define several function pointers and not just one. e.g. thus:

  int function(int x, int y = 1) sum;

could be taken by the compiler to mean

  int function(int x, int y) sum;
//all the rest call back the general function pointer
int function(int x) sum = function sum(int x) { return sum(x,1); }

I haven't explored all of the ramifications of this, but it looks as if it solves quite a few problems without changing the type system, or affecting existing code. And there's a simple model of what's going on: overloading, just generalized slightly.

This may not be clean enough or general enough. But the basic point that something like 'int function(int x, int y = 1)' is a sequence of types is worth attention. A declaration using a sequence of types should produce a sequence of function pointers under this interpretation. Exactly how "sequence of types" and "sequence of pointers" should be wrapped up for best effect is then the language design decision to make. There are several other interesting ways to go, some involving getting more general and allowing other kinds of overloading with function pointer sequences, not just the special kind that comes from default arguments, but I'll stop here for now.




Reply via email to