function pointer question

M

MK

Hello,
I have been trying to get a handle on the following piece of code.
----- BEGIN ----
#include <stdio.h>

int
f2args(int a,int b)
{
printf("a=%d,b=%d\n",a,b);
return 1;
}

typedef int (*func3args)(int,int,int);

int
main(int argc,char **argv)
{
func3args fp = (func3args)f;
fp(1,2,3);
exit(0);
}
----- END ----

weird things:
- I get no compiler warnings or errors (porbably because I used a cast
(func)).
- And when I run I expect the program to crash, but it runs fine.

$ ./a.out
a=1,b=2

My questions are:
- Is this portable and guranteed by the C standard?
- Or is it the manifestation of the C calling convention (the
default), hence not portable or
implementation dependent.
I dug aroung and saw a lot of information regarding 'function pointer
compatibility', I guess I
don't fully understand that.

Thanks
MK
 
R

raxip

I don't even see how that program would compile. Do you mean
'func3args fp = (func3args)f2args'?

If you did, you should get a compiler error complaining about too many
arguements.
 
M

MK

raxip said:
I don't even see how that program would compile. Do you mean
'func3args fp = (func3args)f2args'?

If you did, you should get a compiler error complaining about too many
arguements.

raxip:

I am sorry something went awry with the cut and paste yes it was, here
is the whole
program and compile and run log (Linux x86, gcc 3.3.5).
--- Begin xx.c ----
$ cat xx.c
#include <stdio.h>

int
func2args(int a,int b)
{
printf("a=%d,b=%d\n",a,b);
return 1;
}

typedef int (*func3args)(int,int,int);

int
main(int argc,char **argv)
{
func3args fp = (func3args)func2args;
fp(1,2,3);
exit(0);
}
------------------ End xx.c -------
$ cc xx.c

$ ./a.out
a=1,b=2
 
K

Keith Thompson

MK said:
Hello,
I have been trying to get a handle on the following piece of code.
----- BEGIN ----
#include <stdio.h>

int
f2args(int a,int b)
{
printf("a=%d,b=%d\n",a,b);
return 1;
}

typedef int (*func3args)(int,int,int);

int
main(int argc,char **argv)
{
func3args fp = (func3args)f;
fp(1,2,3);
exit(0);
}
----- END ----

weird things:
- I get no compiler warnings or errors (porbably because I used a cast
(func)).

When I compiled it, I got:

tmp.c: In function `main':
tmp.c:15: error: `f' undeclared (first use in this function)
tmp.c:15: error: (Each undeclared identifier is reported only once
tmp.c:15: error: for each function it appears in.)

I presume your line
func3args fp = (func3args)f;
should be
func3args fp = (func3args)f2args;

If you're going to post code, it's very important to post the *exact*
code that you compiled. Copy-and-paste it, don't re-type it.
- And when I run I expect the program to crash, but it runs fine.
$ ./a.out
a=1,b=2

My questions are:
- Is this portable and guranteed by the C standard?
- Or is it the manifestation of the C calling convention (the
default), hence not portable or
implementation dependent.
I dug aroung and saw a lot of information regarding 'function pointer
compatibility', I guess I
don't fully understand that.

The conversion is ok, but the call invokes undefined behavior.

C99 6.3.2.3p8:

A pointer to a function of one type may be converted to a pointer
to a function of another type and back again; the result shall
compare equal to the original pointer. If a converted pointer is
used to call a function whose type is not compatible with the
pointed-to type, the behavior is undefined.
 
M

MK

Keith,
Thanks for the reply. I did repost the correct code in my reply to
'raxip' post. I apologize. I see from your post that the behavior is
undefined. So what defines the functions 'type'? Is it the just
the 'return type' or the whole signature (including the
parameters?).
The reason I am interested in this, I am looking at a large
code-base, and this 'magic' seems to have been used a lot.
Thanks.
 
I

Ian Collins

MK said:
My questions are:
- Is this portable and guranteed by the C standard?
- Or is it the manifestation of the C calling convention (the
default), hence not portable or
implementation dependent.
I dug aroung and saw a lot of information regarding 'function pointer
compatibility', I guess I
don't fully understand that.
Based on your second post, I'd say it's undefined behaviour which just
happens to wok. Correct me if I'm wrong (I silly thing to say here!),
but I don't think there is a standard calling convention.

A classic case of an evil cast.
 
K

Keith Thompson

MK said:
Keith,
Thanks for the reply. I did repost the correct code in my reply to
'raxip' post. I apologize. I see from your post that the behavior is
undefined. So what defines the functions 'type'? Is it the just
the 'return type' or the whole signature (including the
parameters?).
The reason I am interested in this, I am looking at a large
code-base, and this 'magic' seems to have been used a lot.

The type of a function is determined by the return type and
parameters.

It's possible that your system's calling convention (something not
determined by the C language) is such that this kind of thing happens
to work. You *might* be better off leaving the code as it is,
undefined behavior and all, than fixing it at the risk of introducing
new bugs. You'll have to make that judgement yourself.

And please read <http://cfaj.freeshell.org/google/>.
 
R

Rod Pemberton

MK said:
Keith,
Thanks for the reply. I did repost the correct code in my reply to
'raxip' post. I apologize. I see from your post that the behavior is
undefined. So what defines the functions 'type'? Is it the just
the 'return type' or the whole signature (including the
parameters?).
The reason I am interested in this, I am looking at a large
code-base, and this 'magic' seems to have been used a lot.
Thanks.

Those casts make me think of a few things:

1) A couple of functions with a different number of arguments were merged
together
2) The underlying functions are written in another language, i.e., C
language with Pascal OS calls

The second is common on a number of miniframes.


Rod Pemberton
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,991
Messages
2,570,212
Members
46,800
Latest member
Tobi1987

Latest Threads

Top