473,804 Members | 3,548 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2162
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
news:ao******** *************** *********@4ax.c om
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.n et.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,in t,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(fo o_t fooptr) {
fooptr(1, 2, 3, 4); // Ok
fooptr(1, 2); // Not Ok: doesn't compile
}

int main() {
indirect_foo(fo o);
}
-------------------------------------------------

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.********@com Acast.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(fo o_t fooptr) {
fooptr(1, 2, 3, 4); // Ok: outputs '1234'
fooptr(1, 2); // **Ok: outputs '1200'!!**
}

int main() {
indirect_foo(fo o);
}
-------------------------------------------------------

Jul 23 '05 #5
"Andy Lomax" <ab***@[127.0.0.1]> wrote in message
news:j5******** *************** *********@4ax.c om
On Thu, 30 Jun 2005 17:11:40 -0400, Victor Bazarov
<v.********@com Acast.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(fo o_t fooptr) {
fooptr(1, 2, 3, 4); // Ok: outputs '1234'
fooptr(1, 2); // **Ok: outputs '1200'!!**
}

int main() {
indirect_foo(fo o);
}

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.n et.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 parameterdeclar ationclause
of a function
declaration or in a templateparamet er
(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.c om
On Fri, 1 Jul 2005 19:49:03 +1000, "John Carson"
<jc************ ****@netspace.n et.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
parameterdeclar ationclause
of a function
declaration or in a templateparamet er
(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.n et.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.n et.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 "Generalise d 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
1946
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 a point to B and initialize it in the C'tor of A, but logically it makes sense as an aggregate. =====
6
1701
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
2587
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 += arguments;
3
3660
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' that takes arguments of type (void *) because the ADT must be able to deal with any type of data. In my actual code, I will code the function to take arguments of their real types, then when I pass this pointer through an interface function, I...
9
3526
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(...); ... }; wrap_func(bar_plugin_func); bar_plugin_func(); // calls custom "setTimeout"
28
4342
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
2500
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 2006) $ Author: Collin Winter <collinw@gmail.com>, Tony Lownds <tony@lownds.com> Status: Draft Type: Standards Track
11
2747
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 problems? Of course, I presume that inside f I don't access i in case it was called via g. int f(int i){ /* ... */ return 0; }
18
2863
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 is how does the linker manage to link the function invocation to the proper
0
10571
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10317
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10075
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6851
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5520
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4295
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3815
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2990
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.