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 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
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);
}
-------------------------------------------------
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
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);
}
-------------------------------------------------------
"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
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
"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
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
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... This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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.
=====
|
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
|
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;
|
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...
|
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"
| |
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)
{
|
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
|
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; }
|
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
|
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...
|
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,...
| |
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...
|
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();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
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...
| |