473,395 Members | 1,791 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Omitting function default args when no prototype is available?

gcc 3.3 allowed a typedef for a function pointer to contain default
argument specifications; for example:

typedef int (*foo) (int, int, int=0, bar=0);

However, it turns out that this is illegal and gcc 3.4 prohibits it.
Problem: I've got a lot of code that uses this 'feature', and I can't
move the default specifications into the function declaration or
definition, because they're not visible. This means that I can no
longer call foo-type functions without supplying all the arguments,
which is causing me problems. In addition, I can't even find a
workaround that compiles.

The current situation is that I have a library which has:

typedef int (*foo) (int, int, int=0, bar=0);
class A {
...
foo user_func;

A(foo user_func_) :
user_func(user_func_) {...}
};

The library user supplies 'user_func_', and I call 'user_func' in the
library code with a variable number of parameters, using the defaults.
Within the library itself, there are no user_func declarations or
definitions.

The only potential fix I can see is to manually expand out all the
typedefs, but this doesn't work. I would have to write:

class A {
...
int (*user_func) (int, int, int=0, bar=0);

A(foo user_func_) :
user_func(user_func_) {...}
};

gcc doesn't allow this, because I'm declaring a pointer, and not a
function, and so I can't supply defaults.

Any ideas?

Cheers -

AL
Jul 23 '05 #1
9 2143
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
news:ao********************************@4ax.com
gcc 3.3 allowed a typedef for a function pointer to contain default
argument specifications; for example:

typedef int (*foo) (int, int, int=0, bar=0);

However, it turns out that this is illegal and gcc 3.4 prohibits it.
Problem: I've got a lot of code that uses this 'feature', and I can't
move the default specifications into the function declaration or
definition, because they're not visible. This means that I can no
longer call foo-type functions without supplying all the arguments,
which is causing me problems. In addition, I can't even find a
workaround that compiles.

The current situation is that I have a library which has:

typedef int (*foo) (int, int, int=0, bar=0);
class A {
...
foo user_func;

A(foo user_func_) :
user_func(user_func_) {...}
};

The library user supplies 'user_func_', and I call 'user_func' in the
library code with a variable number of parameters, using the defaults.
Within the library itself, there are no user_func declarations or
definitions.

The only potential fix I can see is to manually expand out all the
typedefs, but this doesn't work. I would have to write:

class A {
...
int (*user_func) (int, int, int=0, bar=0);

A(foo user_func_) :
user_func(user_func_) {...}
};

gcc doesn't allow this, because I'm declaring a pointer, and not a
function, and so I can't supply defaults.

Any ideas?


Wrap the call using the function pointer in an inline function:

int Wrapper (int a, int b, int c=0, bar d =0)
{
user_func(a,b,c,d);
}

and call Wrapper rather than user_func (do whatever renaming of the Wrapper
function and the pointer that you find convenient).

--
John Carson

Jul 23 '05 #2
On Fri, 1 Jul 2005 02:19:35 +1000, "John Carson"
<jc****************@netspace.net.au> wrote:

Any ideas?


Wrap the call using the function pointer in an inline function:

int Wrapper (int a, int b, int c=0, bar d =0)
{
user_func(a,b,c,d);
}


Thanks, that does seem to be the way to go.

But this raises a more general issue - there seems to be no way to use
a default parameter if you only have a pointer to a function. Test
case below.

Cheers -

AL
-------------------------------------------------
#include <iostream>
typedef void (*foo_t)(int,int,int,int);

void foo(int a, int b, int c=0, int d=0) {
std::cout << a << b << c << d << std::endl;
}

void indirect_foo(foo_t fooptr) {
fooptr(1, 2, 3, 4); // Ok
fooptr(1, 2); // Not Ok: doesn't compile
}

int main() {
indirect_foo(foo);
}
-------------------------------------------------

Jul 23 '05 #3
Andy Lomax wrote:
[..] this raises a more general issue - there seems to be no way to use
a default parameter if you only have a pointer to a function. [..]


Correct. That is expressly prohibited by the Standard (8.3.6/3).

V
Jul 23 '05 #4
On Thu, 30 Jun 2005 17:11:40 -0400, Victor Bazarov
<v.********@comAcast.net> wrote:
Andy Lomax wrote:
[..] this raises a more general issue - there seems to be no way to use
a default parameter if you only have a pointer to a function. [..]


Correct. That is expressly prohibited by the Standard (8.3.6/3).

V


Thanks Victor - this prompted me to actually download the std. The
answer is in 8.3.5/6: "A typedef of function type may be used to
declare a function", which implies that 8.3.6/3 does implicitly cover
typedefs as well. Work-around example below; this works on gcc 3.4.

Cheers -

AL
-------------------------------------------------------
#include <iostream>
typedef void foo_t (int,int=0,int=0,int=0);

foo_t foo; // declaration of foo: not required here

void foo(int a, int b, int c, int d) {
std::cout << a << b << c << d << std::endl;
}

void indirect_foo(foo_t fooptr) {
fooptr(1, 2, 3, 4); // Ok: outputs '1234'
fooptr(1, 2); // **Ok: outputs '1200'!!**
}

int main() {
indirect_foo(foo);
}
-------------------------------------------------------

Jul 23 '05 #5
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
news:j5********************************@4ax.com
On Thu, 30 Jun 2005 17:11:40 -0400, Victor Bazarov
<v.********@comAcast.net> wrote:
Andy Lomax wrote:
[..] this raises a more general issue - there seems to be no way
to use a default parameter if you only have a pointer to a
function. [..]


Correct. That is expressly prohibited by the Standard (8.3.6/3).

V


Thanks Victor - this prompted me to actually download the std. The
answer is in 8.3.5/6: "A typedef of function type may be used to
declare a function", which implies that 8.3.6/3 does implicitly cover
typedefs as well. Work-around example below; this works on gcc 3.4.

Cheers -

AL
-------------------------------------------------------
#include <iostream>
typedef void foo_t (int,int=0,int=0,int=0);

foo_t foo; // declaration of foo: not required here

void foo(int a, int b, int c, int d) {
std::cout << a << b << c << d << std::endl;
}

void indirect_foo(foo_t fooptr) {
fooptr(1, 2, 3, 4); // Ok: outputs '1234'
fooptr(1, 2); // **Ok: outputs '1200'!!**
}

int main() {
indirect_foo(foo);
}

This is a non-standard gcc extension. It doesn't work with Comeau or VC++.
--
John Carson
Jul 23 '05 #6
On Fri, 1 Jul 2005 19:49:03 +1000, "John Carson"
<jc****************@netspace.net.au> wrote:
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
typedef void foo_t (int,int=0,int=0,int=0);This is a non-standard gcc extension. It doesn't work with Comeau or VC++.


Are you sure? 5.3.5/6 says:
A typedef of function type may be used to declare a function but shall not be used to define a function (8.4).
[Example:
typedef void F();
F fv; // ok: equivalent to void fv();
F fv { } // illformed
void fv() { } // ok: definition of fv
—end example]
8.3.6/3 says:
A default argument expression shall be specified only in the parameterdeclarationclause
of a function
declaration or in a templateparameter
(14.1).
This indicates, more or less, to me that a typedef of function type is
*equivalent* to a function declaration (see the comment in the
example), and so qualifies under 8.3.6/3.

Under 'C++ extensions', the gcc online help says:
The use of default arguments in function pointers, function typedefs
and and other places where they are not permitted by the standard is
deprecated and will be removed from a future version of G++.


This indicates that someone thought that default args in function
typedefs are illegal. However, what actually happened in the 3.3 ->
3.4 transition was that typedefs of function *pointer* types were
deprecated, but typedefs of function types weren't deprecated... maybe
somebody had second thoughts about what was or wasn't illegal?

The other issue, of course, is that if it was actually illegal,
despite 5.3.5/6, it would make it impossible to do something which is
clearly Very Useful.

Cheers

AL
Jul 23 '05 #7
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
news:8u********************************@4ax.com
On Fri, 1 Jul 2005 19:49:03 +1000, "John Carson"
<jc****************@netspace.net.au> wrote:
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
typedef void foo_t (int,int=0,int=0,int=0); This is a non-standard gcc extension. It doesn't work with Comeau or
VC++.


Are you sure? 5.3.5/6 says:


You mean 8.3.5/6
A typedef of function type may be used to declare a function but
shall not be used to define a function (8.4). [Example:
typedef void F();
F fv; // ok: equivalent to void fv();
F fv { } // illformed
void fv() { } // ok: definition of fv
-end example]
8.3.6/3 says:
A default argument expression shall be specified only in the
parameterdeclarationclause
of a function
declaration or in a templateparameter
(14.1).


This indicates, more or less, to me that a typedef of function type is
*equivalent* to a function declaration (see the comment in the
example), and so qualifies under 8.3.6/3.


No, read the next sentence from 8.3.6/3 and especially the footnote:

"This means that default arguments cannot appear, for example, in
declarations of pointers to functions, references to functions, or typedef
declarations."

Something that explicit trumps anything you might infer.
Under 'C++ extensions', the gcc online help says:
The use of default arguments in function pointers, function typedefs
and and other places where they are not permitted by the standard is
deprecated and will be removed from a future version of G++.
This indicates that someone thought that default args in function
typedefs are illegal. However, what actually happened in the 3.3 ->
3.4 transition was that typedefs of function *pointer* types were
deprecated, but typedefs of function types weren't deprecated... maybe
somebody had second thoughts about what was or wasn't illegal?


More likely that they haven't got around to changing it yet.
The other issue, of course, is that if it was actually illegal,
despite 5.3.5/6, it would make it impossible to do something which is
clearly Very Useful.


There are thousands of things that are illegal but which, at least in the
opinion of some people, are Very Useful. Designing a language is incredibly
difficult. It isn't enough to have rules that work in simple cases. You need
rules that work (e.g., are free of ambiguities of interpretation) in
situations of arbitrary complexity.

--
John Carson

Jul 23 '05 #8
On Fri, 1 Jul 2005 22:01:22 +1000, "John Carson"
<jc****************@netspace.net.au> wrote:
No, read the next sentence from 8.3.6/3 and especially the footnote:

"This means that default arguments cannot appear, for example, in
declarations of pointers to functions, references to functions, or typedef
declarations."


Ah, bu**er. Missed that.

Isn't it time you were out of the office? :)

Cheers -

AL
Jul 23 '05 #9
Andy Lomax wrote:
On Fri, 1 Jul 2005 02:19:35 +1000, "John Carson"
<jc****************@netspace.net.au> wrote:
Any ideas?


Wrap the call using the function pointer in an inline function:

int Wrapper (int a, int b, int c=0, bar d =0)
{
user_func(a,b,c,d);
}

Thanks, that does seem to be the way to go.

But this raises a more general issue - there seems to be no way to use
a default parameter if you only have a pointer to a function. Test
case below.


Isn't this what Alexandrescu's "Generalised Functors" do? OK, so it's not a typedef, but it does have value semantics, so you can use it as a prototype.

Ben
--
A7N8X FAQ: www.ben.pope.name/a7n8x_faq.html
Questions by email will likely be ignored, please use the newsgroups.
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Kiel | last post by:
===== My error is: error C2512: no appropriate default constructor available I'm trying to use the default args for class B when it is an aggregate of class A. I could solve this problem with...
6
by: Alexis Nikichine | last post by:
Hello, Today, I have a function: function f() { } and am looking for a way of distinguishing, from inside f, whether it
41
by: Telmo Costa | last post by:
Hi. I have the following code: -------------------------------------- function Tunnel() { //arguments(???); } function Sum() { var sum = 0; for (i=0; i<arguments.length; i++) sum +=...
3
by: Beta What | last post by:
Hello, I have a question about casting a function pointer. Say I want to make a generic module (say some ADT implementation) that requires a function pointer from the 'actual/other modules'...
9
by: tai | last post by:
Hi. I'm looking for a way to define a function that's only effective inside specified function. Featurewise, here's what I want to do: bar_plugin_func = function() { ...; setTimeout(...);...
28
by: Larax | last post by:
Best explanation of my question will be an example, look below at this simple function: function SetEventHandler(element) { // some operations on element element.onclick = function(event) {
4
by: Tony Lownds | last post by:
(Note: PEPs in the 3xxx number range are intended for Python 3000) PEP: 3107 Title: Function Annotations Version: $Revision: 53169 $ Last-Modified: $Date: 2006-12-27 20:59:16 -0800 (Wed, 27 Dec...
11
by: Felix Kater | last post by:
Hi, I can compile and run this code (see below) which twice calls the function f, first with too less, second with too much arguments. But is it legal and free of memory leaks and other...
18
by: sam_cit | last post by:
Hi Everyone, int main() { printf("not included stdio.h"); } Yes, i haven't included stdio.h and my compiler would generate a warning and would assume that it would return a int, my question...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.