473,372 Members | 1,276 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,372 software developers and data experts.

late-binding of name to function pointer and other questions

Hi all,

I was reading about function pointers and came across something which
intrigued me.
K&R2 calls qsort (pg.119) within main as so:

qsort( (void **) lineptr, 0, nlines-1, (int (*) (void *, void*))(numeric ?
numcmp : strcmp) );

I guess what interests me is the nameless function pointer and then the
binding of a name to it.

I've worked with nameless functions before in other languages but not in C.

So is my reading of this qsort function call correct?

Another question presents itself to me on the following page of K&R2
(pg.120).

/* Declaration qsort */
void qsort( ... )
{
void swap (void *, int, int);
/* ... */
}

It's true you can't declare a function within a function? So that the
forward declaration of swap within qsort doesn't prevent swap from being
called from other functions (since it's defined elsewhere)? So what's the
point of a forward declaration within a function declaration?

Lastly, it is possible to declare a nameless function within a function?
I.e.,
int max20(int a)
{
return { a > 20 ? a : 20 };
}

I mean the {} declares a nameless function, no?
Thanks,
Dennis.
Nov 14 '05 #1
3 2282
Dennis Chang wrote:
Hi all,

I was reading about function pointers and came across something which
intrigued me.
K&R2 calls qsort (pg.119) within main as so:

qsort( (void **) lineptr, 0, nlines-1, (int (*) (void *, void*))(numeric ?
numcmp : strcmp) );

I guess what interests me is the nameless function pointer and then the
binding of a name to it.
Nope. It's not a `nameless function pointer'. It's a cast.
I've worked with nameless functions before in other languages but not in C.

So is my reading of this qsort function call correct?
See above.
Another question presents itself to me on the following page of K&R2
(pg.120).

/* Declaration qsort */
void qsort( ... )
{
void swap (void *, int, int);
/* ... */
}

It's true you can't declare a function within a function? So that the
Sure you can. But you can't *define* a function within a function.
forward declaration of swap within qsort doesn't prevent swap from being
called from other functions (since it's defined elsewhere)? So what's the
point of a forward declaration within a function declaration?

Lastly, it is possible to declare a nameless function within a function?
I.e.,
int max20(int a)
{
return { a > 20 ? a : 20 };
}

I mean the {} declares a nameless function, no?

No.
In fact, the above is *not* standard C code.

HTH,
--ag

--
Artie Gold -- Austin, Texas
Nov 14 '05 #2
Dennis Chang wrote:

I was reading about function pointers and came across something which
intrigued me.
K&R2 calls qsort (pg.119) within main as so:

qsort( (void **) lineptr, 0, nlines-1, (int (*) (void *, void*))(numeric ?
numcmp : strcmp) );
N.B.: The qsort function in their example is not the same as the qsort
function in the C standard library (see page 120 for the qsort function
being used).
I guess what interests me is the nameless function pointer and then the
binding of a name to it.

I've worked with nameless functions before in other languages but not in
C.

So is my reading of this qsort function call correct?
Are you talking about this part:

(int (*) (void *, void*))(numeric ? numcmp : strcmp)

?

I think you're confused about what's going on. First, this expression is
evaluated:

numeric ? numcmp : strcmp

The result of the expression is the address of either numcmp or strcmp,
depending on the value of numeric at run time.

There's a problem here. The type of numcmp's address is:
pointer-to-function-taking-two-char-pointers-and-returning-an-int. The type
of strcmp's address is:
pointer-to-function-taking-two-const-char-pointers-and-returning-an-int
(notice the const). The two operands should be the same type, or at least
the compiler should be able to convert one type to the other automatically.

On page 208 of K&R, the authors write (about the second and third operands
of conditional expressions), "In the type comparison for pointers, any type
qualifiers [like const] in the type to which the pointer points are
insignificant, but the result type inherits qualifiers from both arms of the
conditional."

So it should be okay, but one of the compilers I've tested this code on
gives me an error, and another gives me a warning.

Anyway, let's assume the result of the conditional expression is an address
of type: pointer-to-function taking-two-char-pointers-and-returning-an-int.
What qsort requires for its third parameter is a
pointer-to-function-taking-two-void-pointers-and-returning-an-int. The
conversion between those two types won't happen automatically. So this cast
is added:

(int (*) (void *, void *))

This converts the address to the needed type.

That cast strikes me as suspicious. I'm not sure it's portable.

The authors themselves seem dissatisfied with their example. See their
errata web page:

http://www.cs.bell-labs.com/cm/cs/cbook/2ediffs.html
Another question presents itself to me on the following page of K&R2
(pg.120).

/* Declaration qsort */
void qsort( ... )
{
void swap (void *, int, int);
/* ... */
}

It's true you can't declare a function within a function?
You can declare a function within a function (as above), but you can't
define a function within a function.
So that the
forward declaration of swap within qsort doesn't prevent swap from being
called from other functions (since it's defined elsewhere)?
Well, the declaration is in scope only within qsort. If you need the
declaration to be visible outside qsort, you have to either type the
declaration again, or move the declaration to some other scope.
So what's the point of a forward declaration within a function declaration?

There's no law against it. I can't think of an advantage to doing it that
way. Some people like the style, I guess.
Lastly, it is possible to declare a nameless function within a function?
I.e.,
int max20(int a)
{
return { a > 20 ? a : 20 };
}

I mean the {} declares a nameless function, no?


Well, no. That's a syntax error. There's no such thing as a nameless
function in C.

--
Russell Hanneken
rg********@pobox.com
Remove the 'g' from my address to send me mail.
Nov 14 '05 #3

"Russell Hanneken" <rg********@pobox.com> wrote in message
news:ts***************@newsread1.news.pas.earthlin k.net...
Dennis Chang wrote:

I was reading about function pointers and came across something which
intrigued me.
K&R2 calls qsort (pg.119) within main as so:

qsort( (void **) lineptr, 0, nlines-1, (int (*) (void *, void*))(numeric ? numcmp : strcmp) );
N.B.: The qsort function in their example is not the same as the qsort
function in the C standard library (see page 120 for the qsort function
being used).
I guess what interests me is the nameless function pointer and then the
binding of a name to it.

I've worked with nameless functions before in other languages but not in
C.

So is my reading of this qsort function call correct?


Are you talking about this part:

(int (*) (void *, void*))(numeric ? numcmp : strcmp)

?

I think you're confused about what's going on. First, this expression is
evaluated:

numeric ? numcmp : strcmp

The result of the expression is the address of either numcmp or strcmp,
depending on the value of numeric at run time.

There's a problem here. The type of numcmp's address is:
pointer-to-function-taking-two-char-pointers-and-returning-an-int. The

type of strcmp's address is:
pointer-to-function-taking-two-const-char-pointers-and-returning-an-int
(notice the const). The two operands should be the same type, or at least
the compiler should be able to convert one type to the other automatically.
On page 208 of K&R, the authors write (about the second and third operands
of conditional expressions), "In the type comparison for pointers, any type qualifiers [like const] in the type to which the pointer points are
insignificant, but the result type inherits qualifiers from both arms of the conditional."

So it should be okay, but one of the compilers I've tested this code on
gives me an error, and another gives me a warning.

Anyway, let's assume the result of the conditional expression is an address of type: pointer-to-function taking-two-char-pointers-and-returning-an-int. What qsort requires for its third parameter is a
pointer-to-function-taking-two-void-pointers-and-returning-an-int. The
conversion between those two types won't happen automatically. So this cast is added:

(int (*) (void *, void *))

This converts the address to the needed type.

That cast strikes me as suspicious. I'm not sure it's portable.

The authors themselves seem dissatisfied with their example. See their
errata web page:

http://www.cs.bell-labs.com/cm/cs/cbook/2ediffs.html
Another question presents itself to me on the following page of K&R2
(pg.120).

/* Declaration qsort */
void qsort( ... )
{
void swap (void *, int, int);
/* ... */
}

It's true you can't declare a function within a function?


You can declare a function within a function (as above), but you can't
define a function within a function.
So that the
forward declaration of swap within qsort doesn't prevent swap from being
called from other functions (since it's defined elsewhere)?


Well, the declaration is in scope only within qsort. If you need the
declaration to be visible outside qsort, you have to either type the
declaration again, or move the declaration to some other scope.
So what's the point of a forward declaration within a function

declaration?

There's no law against it. I can't think of an advantage to doing it that
way. Some people like the style, I guess.
Lastly, it is possible to declare a nameless function within a function?
I.e.,
int max20(int a)
{
return { a > 20 ? a : 20 };
}

I mean the {} declares a nameless function, no?


Well, no. That's a syntax error. There's no such thing as a nameless
function in C.

--
Russell Hanneken
rg********@pobox.com
Remove the 'g' from my address to send me mail.


Thanks for both your responses. It's clear now. :O)
Dennis.
Nov 14 '05 #4

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

Similar topics

6
by: Porky | last post by:
Scenario: login/logoff scripts that kick username, times, and dates out to a CSV file. I have a linked table in access pointing to that CSV file. Users typically log in and log out twice a day...
0
by: MarionEll | last post by:
--------------------------------------------------------- ************* Call for Participation ************** ************ Late Breaking News ************* *********** Extreme...
0
by: melledge | last post by:
Deadline for XTECH 2005 Late-Breaking News and Vendor Presentations - 28 March The deadline for submission of Late-Breaking News and Vendor Presentations for IDEAlliance's XTCH 2005...
2
by: hazz | last post by:
how do I do this? I am certain my Visual Studio .NET solution allowed me to do this before but I don't know how the build/debug settings were configured. In order to get around an unavoidable...
1
by: Daniel | last post by:
How do I call a delegate in late bound C# dll? there some way to do this w/ a sharedinterface file? any examples? i tried this but it doesnt work: (oType.GetMethod("IOCTLJOB").Invoke(pObj, new...
5
by: Steve M | last post by:
Why are my sessions lasting so long? I have them set to 20 minute timeout in config file? The Session_End event is getting called an hour or more sometimes--well after the user has stopped...
32
by: whiteboy | last post by:
What's up Everyone? I really need some help. I've been pulling the hair out of my head trying to research how to calculate a late date. Here is what I'm trying to do: DATE VOUCHER...
1
snowman67
by: snowman67 | last post by:
I am writing an RFQ for a software to support my alternativecancer.us web site and need to add a late clause. I haven’t seen any, but I was thinking of a 1% penalty for the first week late and...
13
by: Wayne | last post by:
I have just experienced my first late paying client. By "late" I mean that the invoice is now almost 2 months overdue. I don't think that the client is maliciously withholding payment - rather...
0
by: efftronics | last post by:
Hi, My question is when i log on as a domain user in a computer, which is under domain i am getting very late. What are the reasons for that late. It takes more time for APPLYING YOUR PERSONAL...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.