Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-08-02 13:51:59


On Friday 02 August 2002 02:10 pm, David Abrahams wrote:
> Joel and I are working on a library problem, and he tried something neither
> of us ever expected to work. Surprise! It works with most of our
> more-capable compilers (including recent Comeau). However, we can't find
> any justification for it in the standard. If we're not just exploiting a
> compiler bug here, it could have major implications for Boost.Function,
> Boost.Lambda, et. al. Can anyone point us at standard text which explains
> this? The main issue here is that it looks as though the existence of
> default arguments is getting passed along with a function pointer(!) used
> as a function argument.

We ran across this with Boost.Function once before, and the result was that we
determined Comeau was wrong, and the Boost.Function testcase defarg_test.cpp
was wrong. (I can't seem to find the discussion, unfortunately, though I
removed defarg_test.cpp on Oct 9 of last year).

> Any clues? No wild speculation, please: pointers to standard text is what
> we're after. Thanks:

I think 8.3.6/3 shoots this down:
  "A default argument expression shall be specified only in the
parameterdeclarationclause of a function declaration or in a
templateparameter (14.1). If it is specified in a parameterdeclarationclause,
it shall not occur within a declarator or abstractdeclarator of a
parameterdeclaration."

That says that default arguments aren't part of the type. So to condense your
example:

  template<typename F> call_as_nullary(F f) { f(); }

  int foo(int x = 3, int y = 4);
  call_as_nullary(&f);

8.3.6/3 requires the type F to be int (*)(int, int), without the default
parameters. Then call_as_nullary<int (*)(int, int)> is ill-formed because f()
has too few parameters.

Peter Dimov's example shows the limitation of Comeau's implementation: it gets
the type right, but it fills in the first set of default arguments that it
sees. The caller is responsible for default arguments, so the default
arguments get compiled into call_as_nullary<int (*)(int, int)>.

        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk