parameter and functionpointer

H

humblemark

Hello,

I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??



int ret_integer()
{
return 76;
}


int (*tt(int dummy))()
{

return ((int(*)()) ret_integer());
}


int main()
{ int(*pq)();
pq = tt(23);
pq(); // bang bang
return 0;
}

Thanks a lot C folks
 
M

Martin Ambuhl

humblemark said:
Hello,

I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??


As is often the case, when your code starts filling up with casts, it is
probably wrong. The parameter is not the problem: it is the () on the
return value from tt. And the silly cast can't help; it can only mask
errors. Compare the following:

#include <stdio.h>

int ret_integer()
{
return 76;
}

int (*tt(int dummy)) ()
{
(void) dummy;
return ret_integer;
}

int main()
{
int (*pq) ();
pq = tt(23);
printf("pq() = %d\n", pq());
return 0;
}


[OP's code]
 
G

gw7rib

Hello,

I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??

int ret_integer()
{
return 76;

}

int (*tt(int dummy))()
{

return ((int(*)()) ret_integer());

This line is your problem. ret_integer is a function that returns an
integer. So ret_integer() runs that function, and produces an integer
result (of 76). tt returns that value of 76, horribly cast into a
function pointer. This is, I presume, not what you want. The value you
want out is ret_integer itself, not the result of running it. So miss
off the () after ret_integer, and you get:

return ((int(*)()) ret_integer);

which seems to work fine for me. So well, in fact, that you can miss
out the cast altogether and simply say:

return ret_integer;
}

int main()
{ int(*pq)();
pq = tt(23);
pq(); // bang bang
return 0;

}

Hope that helps.
Paul.
 
K

Keith Thompson

humblemark said:
I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??

The first thing you should do is read
<http://www.catb.org/~esr/faqs/smart-questions.html>.

Telling us that "something went wrong" is not particularly useful.
*What* went wrong?

As it happens, you've given us enough information to figure out the problem.
int ret_integer()
{
return 76;
}

Ok, ``ret_integer'' is a function returning an int. It has no
parameters, but it's better to make that explicit; I'd change the
declaration from ``int reg_integer()'' to ``int reg_integer(void)''.
(This isn't your main problem.
int (*tt(int dummy))()

``tt'' is a function that takes an int argument, and returns a pointer
to a function that returns an int. The returned function takes no
arguments; again, it's better to make this explicit:

int (*tt(int dummy))(void)
{

return ((int(*)()) ret_integer());

The expression ``ret_integer()'' *calls* your function and yields the
value that it returns (76, of type int). You then explicitly convert
the int value 76 to a pointer-to-function type, which gives you garbage.

What you want here is not ``ret_integer()'' (the result of calling the
function), but ``ret_integer'' (the name of the function, which decays
to a pointer to the function in this context).

I'm guessing that you added the cast to silence a compile-time error.
That should have made you suspicious. Most (but not all) casts are
actually unnecessary. All you need here is ``return ret_integer;''.
}


int main()

Ok, but ``int main(void)'' is preferred.
{ int(*pq)();
pq = tt(23);
pq(); // bang bang

And here you try to make a function call through the garbage pointer.
The result is undefined behavior (most likely your program crashes).
return 0;
}

Here's a version of your program that displays the result of the call:

#include <stdio.h>

int ret_integer(void)
{
return 76;
}

int (*tt(int dummy))(void)
{
return ret_integer;
}

int main()
{
int(*pq)(void) = tt(23);
printf("pq() returns %d\n", pq());
return 0;
}
 
F

Flash Gordon

humblemark wrote, On 22/11/07 21:13:
Hello,

I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??

I suggest that you need to learn to use a debugger. Had you done so and
checked the value of pq when you made the call the error would have been
obvious.
int ret_integer()
{
return 76;
}


int (*tt(int dummy))()

Using a typedef for the function type would make this a lot easier to read.
{

return ((int(*)()) ret_integer());

Did you add this case to get rid of a warning? If so you did exactly the
WRONG thing. The case does not fix the code it just stops the compiler
from telling you about your mistake.
return ret_integer;
}


int main()
{ int(*pq)();
pq = tt(23);
pq(); // bang bang
return 0;
}

Thanks a lot C folks

Other general points:

When a function does not take parameters it is better to be explicit so
that the compiler will warn you if you pass parameters in error. E.g.
int (*tt(int dummy))(void)

Using // style comments in posts to Usenet is generally a bad idea
because they do not survive line wrapping.

Please don't use tabs when posting code, sometimes they get stripped by
a server along the way loosing the formatting and other times they are
not rendered by the client in the same way they appear in your editor.
For posting to Usenet always use spaces for indenting.
 
B

Barry Schwarz

Hello,

I try to give a parameter in the function tt; but omething went
wrong?? Any idea what i can do??



int ret_integer()

ret_integer is a function with unspecified arguments returning int
{
return 76;
}


int (*tt(int dummy))()

tt is a function
with a single (unused) parameter of type int
returning a pointer to function
with unspecified arguments
returning type int

The return type of tt matches ret_integer. So far so good.
{

return ((int(*)()) ret_integer());

ret_integer() evaluates to an int. You are attempting to cast this
int to a function pointer. I don't think that is what you want. (What
makes you think there is a valid function at address 76?) I think you
want to return the address of ret_integer. You do this by using the
function name without parentheses. This expression evaluates to the
function address with type pointer to function which I think is what
you do want. The statement should read
return ret_integer;

Since this corrected expression is of type pointer to function with
unspecified arguments returning int, the cast serves no purpose since
it tries to convert the expression to the same type. My crystal ball
tells me you added the cast to silence a diagnostic when your original
code said
return ret_integer();
Let this be the example that convinces you that adding a cast to
silence a diagnostic is ALMOST ALWAYS the wrong solution. Only use a
cast when you are absolutely certain it will do what you want.
}


int main()
{ int(*pq)();
pq = tt(23);
pq(); // bang bang

After you make the above correction, you still have no idea if this
statement worked. Maybe you want to print the value of this
expression.
return 0;
}


Remove del for email
 
J

Justin Spahr-Summers

ret_integer is a function with unspecified arguments returning int

While I wouldn't say it's good practice, an empty parameter list for
the definition of a function means there are no arguments:

6.7.5.3 paragraph 14 (in N1256): "An empty list in a function
declarator that is part of a definition of that function specifies
that the function has no parameters. The empty list in a function
declarator that is not part of a definition of that function specifies
that no information about the number or types of the parameters is
supplied."
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top