LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-04-2013, 07:49 PM   #1
Gullible Jones
Member
 
Registered: Apr 2011
Posts: 142

Rep: Reputation: 10
Function pointers and different sets of arguments


Continuing my queries on function pointers...

I have a situation where a function pointer in a data structure might point to one of two kinds of functions - a function that takes no arguments, or one that takes an integer argument.

I can think of three ways to handle this...

1. Use two function pointer members with different prototypes, one for each type of function. This seems robust (in that compile would probably fail if I referenced the wrong function type), but also a bit ugly and hackish.

2. Give all the functions an integer argument, but do nothing with it unless required. This seems like a terrible hack to me.

3. Use the ellipsis operator, i.e. int (*method)(...); This would be less hackish (assuming I understand it correctly), but it looks like it might introduce runtime bugs if I mess up.

Are there any better ways? If not, which of the above makes the most sense?

Edit: functions that take an argument and never use it don't seem to generate warnings in GCC (with -Wall). This still strikes me as terribly crude though.

Also it looks suboptimal from an efficiency standpoint. My code is not required to perform well, but it should be at least somewhat efficient... And if I have a function taking an integer argument and doing nothing with it, isn't it copying the integer and then throwing it out?

If so, can the compiler optimize out such inefficiencies? Moreover, is it reasonable to depend on the compiler to do that, or should I be handling things in some other, smarter way?

Last edited by Gullible Jones; 05-04-2013 at 09:35 PM.
 
Old 05-05-2013, 03:55 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,735

Rep: Reputation: 490Reputation: 490Reputation: 490Reputation: 490Reputation: 490
> I have a situation where a function pointer in a data structure might point to one of two kinds of functions - a function that takes no arguments, or one that takes an integer argument.

Methinks here is the problem; every structure member (including function pointers) should have one well defined meaning, not 'sometimes this, sometime that'.

PS: functions might ignore their parameters (for example argc and and argv is quite often ignored in minimal test-programs' main function); gcc-option -Wextra warns about that; use __attribute__ ((unused)) to suppress warning.

Last edited by NevemTeve; 05-05-2013 at 04:01 AM.
 
Old 05-05-2013, 11:49 AM   #3
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,446

Rep: Reputation: 829Reputation: 829Reputation: 829Reputation: 829Reputation: 829Reputation: 829Reputation: 829
Quote:
Originally Posted by Gullible Jones View Post
Also it looks suboptimal from an efficiency standpoint. My code is not required to perform well, but it should be at least somewhat efficient... And if I have a function taking an integer argument and doing nothing with it, isn't it copying the integer and then throwing it out?
That's really not the kind of thing to worry about in terms of efficiency. Passing an integer will be 2 instructions (push & pop) for a stack based calling convention (x86), and just a single instruction (setting a register) for register based calling conversion (x86-64). If you hadn't said your code "is not required to perform well" it might be (probably not) worth worrying about the cost of function pointers vs direct calls, but the gain in maintainability and flexibility almost certainly outweighs the tiny performance hit.

Quote:
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil
- Donald Knuth
 
Old 05-15-2013, 02:39 PM   #4
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Regarding the cleanliness of missing/extra arguments, fcntl and open both have an optional third argument. Given the value of the second argument, it only makes sense to look for the third argument in certain cases (e.g. F_SET* and O_CREAT.)

How is it that you can use the same code to call both types of function? How do you have an argument to pass in some cases and not in others, and how do you know when it should be passed to the function? Regardless, you might as well cast them all to void(*)(void) and cast them to the appropriate function type before calling them, since there seems to be other information that allows you to determine the prototype.

I don't know if this is related to the problem, but it seems like it might be:
http://www.newty.de/fpt/functor.html

Even if you're not using C++, the concept might be related to what you're doing in C.

Kevin Barry
 
Old 05-16-2013, 09:57 AM   #5
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,366

Rep: Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106Reputation: 1106
The immediate thought that pops into my mind here is: "hey, we've already got high-level programming languages that know all about that sort of thing." You can define multiple methods to an object, which vary according to the parameter-lists that they take, and any impedance-mismatch problems will be dutifully detected at compile time.

If you do need to use function pointers to get at a particular subroutine, I recommend that you either use two separate pointers (to two separate subroutines), or that you devise the routine ... in whatever programming language you are working with ... to accept a self-describing data structure such as a hash-table as its (perhaps, only) actual input parameter.

Really, though, you do want to find a way to resolve the potential issues with doing this sort of thing, at compile-time. Not at runtime. You are definitely "riding the pony bare-back and without spurs or even a hat" if you do this in C. This requirement is actually quite common, and it has been implemented in the design of a number of mainstream languages.
 
Old 05-17-2013, 02:34 AM   #6
bloody
Member
 
Registered: Feb 2013
Location: Berlin
Distribution: Gentoo, Debian
Posts: 158

Rep: Reputation: 23
Use "-Wall -W" for more warnings, including "unused" warnings for function parameters.

Inside the function, if a parameter named "x" is unused, you can suppress a warning by using:

(void)x;
 
Old 05-17-2013, 08:57 AM   #7
mina86
Member
 
Registered: Aug 2008
Distribution: Slackware
Posts: 374

Rep: Reputation: 150Reputation: 150
You can also put the two pointers into an union if you are worried about size of the structure.

It's really hard to tell more without more details, maybe a short example code of how you using the functions.
 
Old 05-17-2013, 09:23 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
you could use something like:

Code:
int (*func)(void *)
if you must use function pointers.
They are especially good for making your code unreadable and harder to debug.

Worrying about trifling perceived efficiencies is a waste of time in reality.
maintainable, simple code is much much wiser.



Donald Knuth - “premature optimization is the root of all evil,”

Code:
There is no doubt that the grail of efficiency leads to abuse.
 Programmers waste enormous amounts of time thinking about, or worrying about, the speed of
 noncritical parts of their programs, and these attempts at efficiency actually have a strong
 negative impact when debugging and maintenance are considered. We should forget about
 small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

Last edited by bigearsbilly; 05-17-2013 at 09:26 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] How does Curses getmaxyx work with its arguments without them being pointers? tfnc99 Programming 1 02-15-2013 02:44 AM
Why do we need Function Pointers in C? meenakshi.khurana Programming 15 10-11-2011 04:12 AM
[SOLVED] Function pointers with variable arguments kvm1983 Programming 3 07-14-2011 10:12 PM
Pointers/Passing arguments to functions question (C) smoothdogg00 Programming 7 03-17-2006 01:46 PM
Linked Lists: Pointers sent to functions as arguments do not change their valur Jose Muņiz Programming 3 01-12-2004 07:45 PM


All times are GMT -5. The time now is 09:39 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration