Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Function Types"

5 views
Skip to first unread message

rkl...@gmail.com

unread,
Jul 23, 2008, 9:28:18 AM7/23/08
to
Hi,

$4.3 talks about conversion of functions to pointers, specifically "An
lvalue of function type T...". My idea of "function type" is based on
the following article from Herb "http://www.ddj.com/cpp/184401824".

I wrote the following small piece of code.


// CODE SNIPPET 1
int *fn(int *p, const char& rc){return (int *)0;}

typedef int* MYFUNCTIONTYPE(int *, const char&);

void invoke(MYFUNCTIONTYPE t){
(t)(0, 'A');
}

void invoke(MYFUNCTIONTYPE *t){
(*t)(0, 'A');
}

int main(){
invoke(fn);
}

This code is ill-formed because the two versions of invoke are not
sufficiently different to be overloaded as complained by VS2008 and
Comeau.

However a slight modification to use typedef of function pointer,
makes the code perfectly well-formed as expected with the call
resolved to the first version of invoke.


// CODE SNIPPET 2
int *fn(int *p, const char& rc){return (int *)0;}

typedef int* (*MYFUNCTIONTYPE)(int *, const char&); // Changed
to typedef of Function Pointer Type

void invoke(MYFUNCTIONTYPE t){
(t)(0, 'A');
}

void invoke(MYFUNCTIONTYPE *t){
(*t)(0, 'A');
}

int main(){
invoke(fn);
}

So, basically I have two doubts:

a) Why is the first piece of code giving error?

b) $4.3- Does this section talk about the "function type" as in "CODE
SNIPPET 1" or as a more generic term and as interpreted in "CODE
SNIPPET 2"?

Regards,
Dabs

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Thomas Richter

unread,
Jul 23, 2008, 9:37:08 PM7/23/08
to
rkl...@gmail.com wrote:
> Hi,
>
> $4.3 talks about conversion of functions to pointers, specifically "An
> lvalue of function type T...". My idea of "function type" is based on
> the following article from Herb "http://www.ddj.com/cpp/184401824".
>
> I wrote the following small piece of code.
>
>
> // CODE SNIPPET 1
> int *fn(int *p, const char& rc){return (int *)0;}
>
> typedef int* MYFUNCTIONTYPE(int *, const char&);
>
> void invoke(MYFUNCTIONTYPE t){
> (t)(0, 'A');
> }
>
> void invoke(MYFUNCTIONTYPE *t){
> (*t)(0, 'A');
> }
>
> int main(){
> invoke(fn);
> }
>
> This code is ill-formed because the two versions of invoke are not
> sufficiently different to be overloaded as complained by VS2008 and
> Comeau.

In fact, the two types are precisely identical. A function type is
always a pointer to a function.

> However a slight modification to use typedef of function pointer,
> makes the code perfectly well-formed as expected with the call
> resolved to the first version of invoke.
>
>
> // CODE SNIPPET 2
> int *fn(int *p, const char& rc){return (int *)0;}
>
> typedef int* (*MYFUNCTIONTYPE)(int *, const char&); // Changed
> to typedef of Function Pointer Type
>
> void invoke(MYFUNCTIONTYPE t){
> (t)(0, 'A');
> }
>
> void invoke(MYFUNCTIONTYPE *t){
> (*t)(0, 'A');
> }

The second invoke is actually doing something different.It doesn't take
a function pointer argument, but a pointer to a function pointer
argument, i.e. two indirections instead of one. There is no "no
indirection" version of function types, though you may simply strip the
"*" for convenience. (I.e. C doesn't copy code around if you pass a
function as argument to another function, it always only provides the
pointer to the first byte of the code, so to say. That's why (*f)(..)
and f(xx) are identical for a function type).


> a) Why is the first piece of code giving error?

Because you define the same function (namely invoke) twice.

> b) $4.3- Does this section talk about the "function type" as in "CODE
> SNIPPET 1" or as a more generic term and as interpreted in "CODE
> SNIPPET 2"?

SNIPPED 1 is a function type, SNIPPED 2, first function, too, second
function is a pointer to a function type (and a pointer to a pointer to
the actual code called, i.e. f will contain the address of a memory cell
which will contain the address of a function, whereas you only have one
indirection in all other cases).

Greetings,
Thomas

Jiang

unread,
Jul 24, 2008, 4:36:57 AM7/24/08
to
>
> > This code is ill-formed because the two versions of invoke are not
> > sufficiently different to be overloaded as complained by VS2008 and
> > Comeau.
>
> In fact, the two types are precisely identical. A function type is
> always a pointer to a function.
>


The above statement is not true.

function type and pointer-to-function are different, because in 8.3.5/p1,
we have

1. In a declarationT D where D has the form
D1 ( parameter-declaration-clause )
cv-qualifier-seqopt
exception-specificationopt
and the type of the contained declarator-id in the declaration
T D1 is “derived-declarator-type-list T,” the type of the declarator-id
in D is “derived-declarator-type-list function of
(parameter-declaration-clause) cv-qualifier-seqopt returning T”;
a type of this form is a function type.

The above function type has nothing to do with the pointer-to-function type.

However, we do have a standard conversion, which says (in 4.3)

An lvalue of function type T can be converted to an rvalue of
type “pointer to T.” The result is a pointer to the function.


>
> > a) Why is the first piece of code giving error?
>
> Because you define the same function (namely invoke) twice.
>

Because during function overloading, in 13.1.3, we have

- Parameter declarations that differ only in that one is
a function type and the other is a pointer to the same
function type are equivalent. That is, the function type
is adjusted to become a pointer to function type (8.3.5).

therefore, the compiler treat the two invoke function as
the same one. Note this is not because the parameter
declarations are exactly the same, just like you can
not write:

void foo(int array[]) {}
void foo(int *ptr){} // similar rule will reject this one too


> > b) $4.3- Does this section talk about the "function type" as in "CODE
> > SNIPPET 1" or as a more generic term and as interpreted in "CODE
> > SNIPPET 2"?
>
> SNIPPED 1 is a function type, SNIPPED 2, first function, too, second
> function is a pointer to a function type (and a pointer to a pointer to
> the actual code called, i.e. f will contain the address of a memory cell
> which will contain the address of a function, whereas you only have one
> indirection in all other cases).

Well, for the code in SNIPPED 2, since there is no standard conversion
from pointer-to-function to pointer to pointer-to-function, the compiler
can do the overload resolution without any problem.

HTH

0 new messages