Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Function pointers and default arguments

Reply
Thread Tools

Function pointers and default arguments

 
 
claudiu
Guest
Posts: n/a
 
      08-04-2007
Hi,

I'll go straight to the first question. Why does the code below
compile?

void f(int i = 0);

int main()
{
(&f)();
}

My understanding is that the type of &f is void (*)(int) and as such,
expects exactly one argument. However, the default argument of f is
used.

I tried to find out what the standard has to say but I couldn't find
anything explicitly about it (I would appreciate if someone could
point me to the correct paragraph).


The second question, which is how I got to the previous one in the
first place, is how can I "disable" the default arguments of a
function. The reason for this is that I have to call a (large) number
of functions with (lots of) default arguments based on values from an
XML like structure. It's easy enough to read all the arguments from
the XML and directly call the required function but I want the code to
break if someone adds an extra default argument. This way people will
be reminded to ammend the XML code to cope with the extra argument.

The only easy solution I found so far is by using BOOST_TYPEOF.
Something like:

void FunctionWithLotsOfArgs(int, int = 0, double = 1.0, etc);

// read params p1, p2,... from XmL
BOOST_TYPEOF(&FunctionWithLotsOfArgs) fcn = &FunctionWithLotsOfArgs;
fcn(p1, p2,...);

However, there is a problem with this solution. It doesn't work on our
current compiler. We are in the process of migrating to a new version
but it may take a few months before this is completed.

In my opinion, the obvious

void (*FPtr)(int, int, ...) = &FunctionWithLotsOfArgs;
FPtr(p1, p2, ...);

is verbouse enough to put people off. But it works on our compiler.

So, anyone knows any nifty tricks for disabling the default arguments?

Regards,
Claudiu

P.S. Another solution I tried that fails on our compiler (it works on
others) is

template<typename T>
class FuncPtr
{
public:
FuncPtr(const T& ptr) : ptr_(ptr_){}
const T& operator()() const { return ptr_; }
private:
T ptr_;
};

template<typename T>
FuncPtr<T> MakeFuncPtr(const T& ptr)
{
return FuncPtr<T>(ptr);
}

void f(int i = 0);

int main()
{
MakeFuncPtr(&f)()();
}

 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      08-04-2007
claudiu wrote:
> Hi,
>
> I'll go straight to the first question. Why does the code below
> compile?
>
> void f(int i = 0);
>
> int main()
> {
> (&f)();
> }
>
> My understanding is that the type of &f is void (*)(int) and as such,
> expects exactly one argument. However, the default argument of f is
> used.


Default parameters are part of the type.

....
>
> The second question, which is how I got to the previous one in the
> first place, is how can I "disable" the default arguments of a
> function. ...



The code below does somthing like what you're looking at doing.
-----
// This F() takes function pointers of functions with no params
template <typename Tr>
Tr (* F( Tr (*fp)( ) ) )( )
{
return fp;
}

// This F(fp) takes function pointers of functions with 1 param
template <typename Tr, typename T1>
Tr (* F( Tr (*fp)( T1 ) ) )( T1 )
{
return fp;
}

// This F(fp) takes function pointers of functions with 2 params
template <typename Tr, typename T1, typename T2>
Tr (* F( Tr (*fp)( T1, T2 ) ) )( T1, T2 )
{
return fp;
}

// F(fp) may be extended to as many parameters you may want to handle


// test code
int Z( int i = 0)
{
return i;
}

int X( int i = 0, double d = 4.4)
{
return i;
}

int main()
{
Z();
X();

// works
F( Z )(5);
F( X )( 1, 1.1 );

// fails
//F( Z )();
//F( X )( 1 );
}
-----

This defines a number of overloaded F template functions that take
pointers to functions of different numbers of parameters and return the
pointer. The parameters do not define a "default" so the type of the
functions returned do not have default parameters but are otherwise the
same as the function passed in.
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      08-04-2007
On Aug 5, 12:23 am, Gianni Mariani <(E-Mail Removed)> wrote:
> claudiu wrote:
> > I'll go straight to the first question. Why does the code below
> > compile?


> > void f(int i = 0);


> > int main()
> > {
> > (&f)();
> > }


> > My understanding is that the type of &f is void (*)(int) and as such,
> > expects exactly one argument. However, the default argument of f is
> > used.


> Default parameters are part of the type.


No they're not. The type of the function f, above, is void
(int). Try it:
void (*pf)( int ) = &f ;
or even:
void (*pf)( int i = 42 ) = &f ;

The reason the default arguments are used in his case is because
the expression invoking the function has default arguments
associated with it.

--
James Kanze (GABI Software) email:james.kanze:gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      08-05-2007
James Kanze wrote:
> On Aug 5, 12:23 am, Gianni Mariani <(E-Mail Removed)> wrote:
>> claudiu wrote:
>>> I'll go straight to the first question. Why does the code below
>>> compile?

>
>>> void f(int i = 0);

>
>>> int main()
>>> {
>>> (&f)();
>>> }

>
>>> My understanding is that the type of &f is void (*)(int) and as such,
>>> expects exactly one argument. However, the default argument of f is
>>> used.

>
>> Default parameters are part of the type.

>
> No they're not. The type of the function f, above, is void
> (int). Try it:
> void (*pf)( int ) = &f ;
> or even:
> void (*pf)( int i = 42 ) = &f ;
>
> The reason the default arguments are used in his case is because
> the expression invoking the function has default arguments
> associated with it.


Interesting; this code compiles in gcc but not on comeau or VC++ 2005.

int f( int p = 5 )
{
return p;
}

template <typename T>
T F( T fp )
{
return fp;
}

#include <iostream>

int main()
{
std::cout << F( f )() << "\n";
}

Ok, so who is wrong, GCC or Comeau + VC++ ?
 
Reply With Quote
 
Greg Herlihy
Guest
Posts: n/a
 
      08-05-2007
On Aug 4, 5:13 pm, Gianni Mariani <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > On Aug 5, 12:23 am, Gianni Mariani <(E-Mail Removed)> wrote:
> >> claudiu wrote:
> >>> I'll go straight to the first question. Why does the code below
> >>> compile?

>
> >>> void f(int i = 0);

>
> >>> int main()
> >>> {
> >>> (&f)();
> >>> }

>
> >>> My understanding is that the type of &f is void (*)(int) and as such,
> >>> expects exactly one argument. However, the default argument of f is
> >>> used.

>
> >> Default parameters are part of the type.

>
> > No they're not. The type of the function f, above, is void
> > (int). Try it:
> > void (*pf)( int ) = &f ;
> > or even:
> > void (*pf)( int i = 42 ) = &f ;

>
> > The reason the default arguments are used in his case is because
> > the expression invoking the function has default arguments
> > associated with it.

>
> Interesting; this code compiles in gcc but not on comeau or VC++ 2005.
>
> int f( int p = 5 )
> {
> return p;
>
> }
>
> template <typename T>
> T F( T fp )
> {
> return fp;
>
> }
>
> #include <iostream>
>
> int main()
> {
> std::cout << F( f )() << "\n";
>
> }
>
> Ok, so who is wrong, GCC or Comeau + VC++ ?


gcc is wrong in this case - and acknowledges it:

"The use of default arguments in function pointers, function typedefs
and other places where they are not permitted by the standard is
deprecated and will be removed from a future version of G++"

from http://gcc.gnu.org/onlinedocs/gcc-4....cated-Features

Greg



 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      08-05-2007
Greg Herlihy wrote:
....
>> Ok, so who is wrong, GCC or Comeau + VC++ ?

>
> gcc is wrong in this case - and acknowledges it:
>
> "The use of default arguments in function pointers, function typedefs
> and other places where they are not permitted by the standard is
> deprecated and will be removed from a future version of G++"
>
> from http://gcc.gnu.org/onlinedocs/gcc-4....cated-Features


I think they only fixed half the bug.

It appears that it only seems to work sometimes.

int f1( int p = 5 )
{
return p;
}

int f2( int p )
{
return p;
}

double d1( double p )
{
return p;
}

double d2( double p = 1.1 )
{
return p;
}

template <typename T>
T F( T fp )
{
return fp;
}

#include <iostream>

int main()
{

std::cout << F( f1 )() << "\n";
std::cout << F( f2 )() << "\n";

std::cout << F( d1 )() << "\n";
std::cout << F( d2 )() << "\n";
}


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      08-05-2007
Gianni Mariani wrote:
> Greg Herlihy wrote:
> ...
>>> Ok, so who is wrong, GCC or Comeau + VC++ ?

>>
>> gcc is wrong in this case - and acknowledges it:
>>
>> "The use of default arguments in function pointers, function typedefs
>> and other places where they are not permitted by the standard is
>> deprecated and will be removed from a future version of G++"
>>
>> from
>> http://gcc.gnu.org/onlinedocs/gcc-4....cated-Features
>>

>
> I think they only fixed half the bug.


Bug filed:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32993
 
Reply With Quote
 
claudiu
Guest
Posts: n/a
 
      08-05-2007
Gianni,

Thanks for the solution! It seems to work with our compiler.

> The reason the default arguments are used in his case is because
> the expression invoking the function has default arguments
> associated with it.
>


James,

What do you mean by that last sentence?. The expression invoking the
function is (&f)(). How are the default arguments associated with it?

Regards,
Claudiu

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-05-2007
On Aug 5, 2:13 am, Gianni Mariani <(E-Mail Removed)> wrote:
> James Kanze wrote:


[Note that as far as I can tell, this comment has nothing to
do with what preceding in the thread.]
> Interesting; this code compiles in gcc but not on comeau or VC++ 2005.


> int f( int p = 5 )
> {
> return p;
> }


> template <typename T>
> T F( T fp )
> {
> return fp;
> }


> #include <iostream>


> int main()
> {
> std::cout << F( f )() << "\n";
> }


> Ok, so who is wrong, GCC or Comeau + VC++ ?


What operator<< is being called? The type of F(f) is "int (*)(
int )" (a "function" type is treated as a pointer to function
type when it is a function parameter). There's no such
operator<< in the standard, and there's no implicit conversion
from a function pointer to anything which has an operator<<, so
a priori, it shouldn't compile.

What does the output look like? Could it be that g++ is
(illegally) converting the function pointer to void*?

--
James Kanze (GABI Software) email:james.kanze:gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      08-05-2007
On Aug 5, 1:59 pm, claudiu <(E-Mail Removed)> wrote:
> Gianni,


> Thanks for the solution! It seems to work with our compiler.


> > The reason the default arguments are used in his case is because
> > the expression invoking the function has default arguments
> > associated with it.


> What do you mean by that last sentence?. The expression invoking the
> function is (&f)(). How are the default arguments associated with it?


I'm not too sure of the exact rules myself, but the expression f
designates a function for which a default argument is provided.
While not part of the type, default arguments do propagate
through expressions, remaining attached to the expression.

Consider, for example:

int f( int = 42 ) ;
int g( int ) ;

// ....
assert( typeid( f ) == typeid( g ) ) ;

But of course, f(), (&f)(), etc. remain legal.

--
James Kanze (GABI Software) email:james.kanze:gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Member function pointers to member functions with default arguments Hamish C++ 3 01-25-2008 06:46 AM
how to pass a function name and its arguments inside the arguments of other function? jmborr Python 1 11-03-2007 08:20 AM
function default arguments from other arguments tutmann C++ 4 10-17-2006 08:00 PM
Difference between default arguments and keyword arguments Edward Diener Python 14 04-05-2004 11:26 PM



Advertisments