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

Re: function name as function pointer

Stephen Sprunk said:

<snip>
A function name decays to a pointer-to-function in most contexts just
like an array of foo decays to a pointer-to-foo in most contexts.
Almost.

A function name *is* a pointer-to-function. You can do two things with it -
copy it (assign its value to an object of function pointer type, with a
cast if necessary but preferably to one of the /right/ function pointer
type!), or call it (by dereferencing it and supplying a (possibly empty)
parameter list. There is no "decay" involved.

As a special ANSI (and thus ISO) dispensation, you can omit the dereference
operator. Thus, given:

int (*foo)(int) = isspace;

this is legal:

int x = (*foo)('A')';

and so is this:

int y = foo('A');

and so, would you believe, is this:

int z = (*****foo)('A');

This is very UNlike the rule for arrays. Given char bar[32]; the identifier
bar does indeed decay to a pointer to its first element when used in a
value context. Nevertheless, you can take its address - &bar - and this
gives you, not a char *, but a char (*)[32]. You can dereference it - *bar
- but this gives you a char, not a char *. And you can hand it to sizeof,
which you can't do with function pointers.

(This is partly a minor rebuttal to Stephen's point, but mostly an
expansion of it - I know Stephen knows this stuff.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 9 '08 #1
10 3532
On Tue, 09 Sep 2008 16:58:23 +0000, Richard Heathfield wrote:
Stephen Sprunk said:

<snip>
>A function name decays to a pointer-to-function in most contexts just
like an array of foo decays to a pointer-to-foo in most contexts.

Almost.

A function name *is* a pointer-to-function.
No, it's not. The name of a function, when used in an expression, has
function type. Except when it's the operand of unary & or sizeof, it is
converted to pointer-to-function.
This is very UNlike the rule for arrays. Given char bar[32]; the
identifier bar does indeed decay to a pointer to its first element when
used in a value context.
Similar to how a function decays to a function pointer?
Nevertheless, you can take its address - &bar -
and this gives you, not a char *, but a char (*)[32].
Similar to how you can take an int(void)'s address, and this gives you not
an int, but an int(*)(void)?
You can
dereference it - *bar - but this gives you a char, not a char *.
No, you can't dereference an array, but you can dereference a pointer to
an array's initial element. What would be the syntax for the former, if it
were valid, is actually the syntax for the latter.

int x[2];
*x;

The operand of unary * has type int *. It is the result of the decay of an
array to a pointer.
And you
can hand it to sizeof, which you can't do with function pointers.
Which you can do with function pointers, but which you can't do with
functions. However, the fact that you cannot take a function's size has
nothing to do with its decay to a pointer to a function.
Sep 9 '08 #2
Richard Heathfield <rj*@see.sig.invalidwrites:
Stephen Sprunk said:

<snip>
>A function name decays to a pointer-to-function in most contexts just
like an array of foo decays to a pointer-to-foo in most contexts.

Almost.

A function name *is* a pointer-to-function. You can do two things with it -
copy it (assign its value to an object of function pointer type, with a
cast if necessary but preferably to one of the /right/ function pointer
type!), or call it (by dereferencing it and supplying a (possibly empty)
parameter list. There is no "decay" involved.
[...]

Stephen is right, and you are mistaken.

C99 6.3.2.1p4:

A _function designator_ is an expression that has function
type. Except when it is the operand of the sizeof operator or the
unary & operator, a function designator with type "function
returning _type_" is converted to an expression that has type
"pointer to function returning _type_".

with a footnote:

Because this conversion does not occur, the operand of the sizeof
operator remains a function designator and violates the constraint
in 6.5.3.4.

(I think C90 has similar wording, but my copy is messed up at the
moment.)

A function name is one example of an expression that has function
type. The value of that expression, in most contexts, is converted to
(i.e., "decays" to) a pointer to the function.
As a special ANSI (and thus ISO) dispensation, you can omit the dereference
operator. Thus, given:

int (*foo)(int) = isspace;

this is legal:
Right, because the expression ``isspace'' is implicitly converted from
a function type to a pointer-to-function-type.
int x = (*foo)('A')';
foo is of pointer-to-function type. It's dereferenced, yielding a
value of functiont type, which is immediately converted to
pointer-to-function type -- which is just what's needed for the
function call "operator" (the standard doesn't call it an operator).
and so is this:

int y = foo('A');
Right, no conversion is necessary.
and so, would you believe, is this:

int z = (*****foo)('A');
*foo, as above, is of pointer-to-function type. **foo is of function
type, and decays to pointer-to-function type. ***foo is of function
type, and decays to pointer-to-function type. And so on.
This is very UNlike the rule for arrays. Given char bar[32]; the identifier
bar does indeed decay to a pointer to its first element when used in a
value context. Nevertheless, you can take its address - &bar - and this
gives you, not a char *, but a char (*)[32]. You can dereference it - *bar
- but this gives you a char, not a char *. And you can hand it to sizeof,
which you can't do with function pointers.
It's almost exactly like the rule for arrays, except that a function
decays to a pointer to the function itself whereas an array name
decays to a pointer to the array's first element. Given
void func(void);
``func'' decays to a pointer to the function when used in a value
context. You can take its address, ``&func'' (this a case where the
decay doesn't happen), and this gives you the address of the function.
You can dereference it, ``*func''; this gives an expression of
function type that immediately decays back to a pointer-to-function.
You can't do ``sizeof func'' but only because the constraint in C99
6.5.3.4p1 specifically disallows it.
(This is partly a minor rebuttal to Stephen's point, but mostly an
expansion of it - I know Stephen knows this stuff.)
I hope not. 8-)}

It's likely that the rules you describe yield identical results to the
rules in the standard, but they're not what the standard says.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #3
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
<snip>
>(This is partly a minor rebuttal to Stephen's point, but mostly an
expansion of it - I know Stephen knows this stuff.)

I hope not. 8-)}

It's likely that the rules you describe yield identical results to the
rules in the standard, but they're not what the standard says.
WELL! I sit corrected. Apologies to Stephen for an incorrect "correction".

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 9 '08 #4
On Sep 9, 10:16 pm, Harald van D©¦k <true...@gmail.comwrote:
On Tue, 09 Sep 2008 16:58:23 +0000, Richard Heathfield wrote:
Stephen Sprunk said:
<snip>
A function name decays to a pointer-to-function in most contexts just
like an array of foo decays to a pointer-to-foo in most contexts.
Almost.
A function name *is* a pointer-to-function.

No, it's not. The name of a function, when used in an expression, has
function type. Except when it's the operand of unary & or sizeof, it is
converted to pointer-to-function.
This is very UNlike the rule for arrays. Given char bar[32]; the
identifier bar does indeed decay to a pointer to its first element when
used in a value context.

Similar to how a function decays to a function pointer?
Nevertheless, you can take its address - &bar -
and this gives you, not a char *, but a char (*)[32].

Similar to how you can take an int(void)'s address, and this gives you not
an int, but an int(*)(void)?
You can
dereference it - *bar - but this gives you a char, not a char *.

No, you can't dereference an array, but you can dereference a pointer to
an array's initial element. What would be the syntax for the former, if it
were valid, is actually the syntax for the latter.

int x[2];
*x;

The operand of unary * has type int *. It is the result of the decay of an
array to a pointer.
And you
can hand it to sizeof, which you can't do with function pointers.
I was able to do the sizeof with function pointer. There should be no
problem with it.

>
Which you can do with function pointers, but which you can't do with
functions. However, the fact that you cannot take a function's size has
nothing to do with its decay to a pointer to a function.
Sep 9 '08 #5
Richard Heathfield wrote:
Stephen Sprunk said:
>A function name decays to a pointer-to-function in most contexts just
like an array of foo decays to a pointer-to-foo in most contexts.

Almost.

A function name *is* a pointer-to-function. You can do two things with it -
copy it (assign its value to an object of function pointer type, with a
cast if necessary but preferably to one of the /right/ function pointer
type!), or call it (by dereferencing it and supplying a (possibly empty)
parameter list. There is no "decay" involved.
The problem with your explanation is that "&func" gives a
pointer-to-function. If "func" itself were a pointer-to-function,
"&func" would give a pointer-to-pointer-to-function. In reality, "func"
decays to pointer-to-function except in certain cases, e.g. when it's
the object of the unary & -- just line an array.

(Or, at least, it _acts_ like that's what happens.)
This is very UNlike the rule for arrays. Given char bar[32]; the identifier
bar does indeed decay to a pointer to its first element when used in a
value context. Nevertheless, you can take its address - &bar - and this
gives you, not a char *, but a char (*)[32]. You can dereference it - *bar
- but this gives you a char, not a char *.
I may be unclear on the details there. If "*arr" gives you a char, then
it stands to reason "arr" has decayed to a pointer-to-char.
And you can hand it to sizeof, which you can't do with function pointers.
Right; that would be one of the exceptions to the decay. If "func" were
a pointer-to-function, then "sizeof func" would give the size of a
pointer-to-function. Without the decay, it would need to give the size
of the function itself, which is undefined since functions aren't objects.
(This is partly a minor rebuttal to Stephen's point, but mostly an
expansion of it - I know Stephen knows this stuff.)
However, I sometimes get sloppy in my explanations due to not
understanding the fine distinctions of jargon. I welcome corrections
from the pedants.

S
Sep 9 '08 #6
sh******@gmail.com writes:
[...]
>On Tue, 09 Sep 2008 16:58:23 +0000, Richard Heathfield wrote:
[...]
And you
can hand it to sizeof, which you can't do with function pointers.

I was able to do the sizeof with function pointer. There should be no
problem with it.
[...]

Right, you can apply sizeof to an expression of pointer-to-function
type, such as the name of an object of pointer-to-function type.

The point is that a function name does not "decay" to a pointer when
it's the operand of a unary sizeof or "*" operator. For example,
given a function named "func", the expression `sizeof func'' doesn't
yield the size of a pointer to the function; instead, it's a
constraint violation. (Normally ``func'', after the decay, is of
pointer-to-function type, but the decay doesn't occur in this
context.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #7
Keith Thompson <ks***@mib.orgwrites:
[...]
C99 6.3.2.1p4:

A _function designator_ is an expression that has function
type. Except when it is the operand of the sizeof operator or the
unary & operator, a function designator with type "function
returning _type_" is converted to an expression that has type
"pointer to function returning _type_".

with a footnote:

Because this conversion does not occur, the operand of the sizeof
operator remains a function designator and violates the constraint
in 6.5.3.4.

(I think C90 has similar wording, but my copy is messed up at the
moment.)
[..]

The wording in C90 is identical (apart from the section reference in
the footnote).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #8
Keith Thompson <ks***@mib.orgwrites:

[...]
Right, you can apply sizeof to an expression of pointer-to-function
type, such as the name of an object of pointer-to-function type.

The point is that a function name does not "decay" to a pointer when
it's the operand of a unary sizeof or "*" operator.
Of course, what you meant to say is that a function name isn't
converted to pointer-to-function when it's the operand of
a unary "&" operator.
Sep 9 '08 #9
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
Keith Thompson <ks***@mib.orgwrites:

[...]
>Right, you can apply sizeof to an expression of pointer-to-function
type, such as the name of an object of pointer-to-function type.

The point is that a function name does not "decay" to a pointer when
it's the operand of a unary sizeof or "*" operator.

Of course, what you meant to say is that a function name isn't
converted to pointer-to-function when it's the operand of
a unary "&" operator.
Yes, thanks. (D'oh!)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '08 #10
On Tue, 09 Sep 2008 10:27:14 -0700, Keith Thompson <ks***@mib.org>
wrote:
<snip>
Stephen is right, and you are mistaken.

C99 6.3.2.1p4: <snip>
int x = (*foo)('A')';

foo is of pointer-to-function type. It's dereferenced, yielding a
value of functiont type, which is immediately converted to
pointer-to-function type -- which is just what's needed for the
function call "operator" (the standard doesn't call it an operator).
<snip correct semantics and examples>

Nit: it isn't explicitly named an operator, but it is placed within
6.5.2 (formerly 6.3.2) Postfix Operators. In C90 it is indexed as
'function-call operator' once (under parens) and just 'function call'
once; in C99 these are both (consistently) 'function-call operator'.
Although neither of these is AFAICS officially a defined term (i.e.
italicized) so the distinction doesn't really matter.

C also classifies as operators member selection, (array) subscripting,
cast (for type conversion), and (C99 only) compound literals. In
(most?) other HLLs at least the first two, sometimes third, and fourth
if applicable, are considered (syntactically) forms of primary or
other specific NT, rather than expressions containing operators.
Array subscripting in C, and B and BCPL before it, is truly 'just' an
operation and hence reasonably an operator, and into early (very
prestandard) C member selection was very close; function call is
similarly partly operatorish: its left operand is 'just' a (possibly
computed) (r)value but its right operand is special. I think compound
literals were simply shoehorned in there for convenience, much as
typedef is a storage-class syntactically but not semantically.

Similarly, C calls assignment an operator/operation (actually a series
of them e.g. = *= ++ etc.), and lets it be nested; most(?) other HLLs
call it a form(s) of statement, thus allowing it only at top level
(or implicitly in by-value call and return and initialization).
C does call a parenthesized (sub)expression a form of primary.
OT&FWIW, C++ calls :: an operator, the 'scope resolution operator',
even though both/all its operands are compiletime identifiers.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Sep 22 '08 #11

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

Similar topics

58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
11
by: Edd | last post by:
Hello all, I've made a data structure and an associated set of functions to enable me to store a dynamically-sized array of elements of whatever data type I like. Well that's the idea anyway......
27
by: Marlene Stebbins | last post by:
I am experimenting with function pointers. Unfortunately, my C book has nothing on function pointers as function parameters. I want to pass a pointer to ff() to f() with the result that f() prints...
38
by: maadhuu | last post by:
does it make sense to find the size of a function ??? something like sizeof(main) ??? thanking you ranjan.
12
by: mohan | last post by:
Hi All, How to implement virtual concept in c. TIA Mohan
3
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'...
3
by: Daniel Kraft | last post by:
Hi, I was curious whether or not to use the & operator when creating a function pointer. It seems, that both &func and plain func create a pointer of the appropriate function pointer type. ...
7
by: dries | last post by:
Hello lads, I'd like to do the following in C: 1. The user writes a function with predefined arguments and return value in a separate file. 2. The program is compiled as my written 'main'...
26
by: aruna.mysore | last post by:
Hi all, I have a specific problem passing a function pointer array as a parameter to a function. I am trying to use a function which takes a function pointer array as an argument. I am too sure...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
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: 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:
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...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

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.