C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old April 8th, 2003, 12:10 PM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 11
function pointer stuff

this function call line is confusing me a bit:
Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(fold ? strcmpulc : strcmp));

i don't understand what the (void **) part is. it doesn't match up with the qsorty decleration which is:
Code:
void qsorty(void *lineptr[], int left, int right, int (*comp)(void *, void *));


also the (int (*)(void *, void *))(fold ? strcmpulc : strcmp) part from the function call i kind of understand. it seems that it's working a bit like the %d's in a printf statement - the place holder is getting replaced. so (*) is getting replaced by the answer to fold ? which is going to be one of the two pointers to functions.

what is that makes it behave like that? is that something to do with the (void **) maybe? (i'm guessing)

also, say you've got a situation where there isn't any option about which function pointer should be passed (like in the (fold ? strcmpulc : strcmp) part), is this the only way to say that? :
Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numcmp));

that works but it seems like it should be possible to use something like:
Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*numcmp)(void *, void *)));

or
Code:
qsorty((void **) lineptr, 0, nlines-1, (*numcmp)(void *, void *));

but they aren't ok.

Reply With Quote
  #2  
Old April 8th, 2003, 01:23 PM
Analyser's Avatar
Analyser Analyser is offline
*bounce*
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Delft, The Netherlands
Posts: 513 Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 2 Days 22 h 45 m 12 sec
Reputation Power: 41
Send a message via ICQ to Analyser
Quote:
i don't understand what the (void **) part is. it doesn't match up with the qsorty declaration...


Bear in mind that in a function declaration (and only in a function declaration!) pointer-to-type and array-of-type are identical; they're synonymous, and the only reason why you might want to choose array-of-type (type[]) over pointer-to-type (type*) is as a hint to the programmer that it doesn't point to a single element of type, but to the first in a sequence of type.

In the function call I assume that lineptr is an array of pointer-to-char, which is why the typecast to (void **) makes sense, being that in a function declaration, **void is identical to *void[] as I just explained.

Quote:
also the (int (*)(void *, void *))(fold ? strcmpulc : strcmp) part from the function call i kind of understand. it seems that it's working a bit like the %d's in a printf statement - the place holder is getting replaced. so (*) is getting replaced by the answer to fold ? which is going to be one of the two pointers to functions.


Let's break that up into two pieces, the first part being a typecast, and the second being the conditional operator:

The (fold ? strcmpulc : strcmp) bit is fairly straight-forward; it's the conditional operator ?: (check A7.16 on page 208 of K&R if you're unfamiliar with it).

Basically that expression evaluates to either strcmpulc or strcmp, depending on the value of fold. So what you get, is a function pointer.

The problem is that qsorty expects a pointer to a function that has a prototype of
Code:
int (*cmp)(void *, void *)


, but strcmp and strcmpulc are (probably) declared as
Code:
int (*cmp)(const char *, const char *)


That's what the typecast is for. It might look draconian, but yes, it really is a typecast. It casts the pointer-to-function-with-two-pointer-to-char-arguments-and-returning-an-int
to a pointer-to-function-with-two-pointer-to-void-arguments-and-returning-an-int.

Code:
int (*)(void *, void *)


can be broken down as follows:

Code:
int              /* returning an int */
(*)              /* pointer-to */
(void *, void *) /* function with two pointer-to-void arguments */


It needs the parentheses around the asterisk (the pointer-to bit) to make sure it isn't associated with the return type, int.

I hope this clears things up a bit. Keep asking though; it keeps us on our toes
__________________
"A poor programmer is he who blames his tools."
http://analyser.oli.tudelft.nl/

Reply With Quote
  #3  
Old April 9th, 2003, 08:50 AM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 11
thanks for your reply.
Quote:
, but strcmp and strcmpulc are (probably) declared as
Code:
int (*cmp)(const char *, const char *)

they're just declared normally :
Code:
int strcmpulc(char *, char *);

and the other is part of string.h so it's also declared in the usual way. maybe that's why i get :

warning: pointer type mismatch in conditional expression

for that line? probably is. but then saying that, on this function call line:
Code:
qsorty((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numcmp));

i don't get that warning and numcmp is declared like so:
Code:
int numcmp(char *, char *);





Quote:
(int (*)(void *, void *))(fold ? strcmpulc : strcmp)

two pieces, the first part being a typecast, and the second being the conditional operator

i understand that apart from why, when there's no conditional aspect - only one possible function to call, can i not say:
Code:
(int (*strcmp)(void *, void *))

or something similar? does it have to be in two pieces even when no conitional element? (in the call to the function that is)

Quote:
I hope this clears things up a bit.

a bit, yes thanks i need to go over it a bit more to let it sink in

Last edited by balance : April 9th, 2003 at 08:57 AM.

Reply With Quote
  #4  
Old April 9th, 2003, 02:29 PM
Analyser's Avatar
Analyser Analyser is offline
*bounce*
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Delft, The Netherlands
Posts: 513 Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 2 Days 22 h 45 m 12 sec
Reputation Power: 41
Send a message via ICQ to Analyser
Quote:
they're just declared normally


Well, my emphasis wasn't on the consts, but the fact that it's char* instead of void*.

Quote:
I understand that apart from why, when there's no conditional aspect - only one possible function to call, can i not say:

Code:
(int (*strcmp)(void *, void *))


or something similar? does it have to be in two pieces even when no conitional element?


The code snippet above is just a semi-colon short of a declaration statement. It would declare strcmp as being a pointer-to-function. What the qsorty function call contains though, is a type cast, which has a general form of

Code:
(type-to-cast-to) (expression-to-cast)


Just like you can cast a real expression to an integer expression by saying (int)(3.14159), you can cast pointer-to-function expressions.

The thing is that not all function pointers are alike; some pointers point to a function that takes an int as an argument, others point to a function that returns a double, etc, etc. They're all different, because the functions' declarations are different.

Hence, when you've defined a function (qsorty in this case) that expects as its third parameter a pointer to a function that takes two pointer-to-void arguments, and you call it with its third argument being a pointer to a function that takes two pointer-to-char arguments (strcmp, for example), then you'll get a warning (if not error) saying that the types don't match. That's why you have to perform a type cast.

Quote:
i don't get that warning and numcmp is declared like so


Again, that would be due to the type cast

Reply With Quote
  #5  
Old April 11th, 2003, 10:31 AM
balance balance is offline
.
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2002
Posts: 296 balance User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 11
ok i think i've got it. thanks-a-lot for your explenation analyser

Reply With Quote
  #6  
Old April 11th, 2003, 10:37 AM
Analyser's Avatar
Analyser Analyser is offline
*bounce*
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2002
Location: Delft, The Netherlands
Posts: 513 Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level)Analyser User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 2 Days 22 h 45 m 12 sec
Reputation Power: 41
Send a message via ICQ to Analyser
You're quite welcome

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > function pointer stuff

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap