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

Problem with pointer to function - what's wrong here?

I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};

int func1(<argument list>)
{
<blah-blah-blah1>
}

int func2(<argument list>)
{
<blah-blah-blah2>
}

I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?

Thanks for your help.

Regards,
Charles Sullivan


Jan 31 '07 #1
6 2180
Charles Sullivan <cw******@triad.rr.comwrites:
int (*myfunc)();
[...]
I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"
The problem is that there is no way to call a function with that
prototype, through a function pointer without a prototype,
without invoking undefined behavior. The reason is that, when
you invoke a function for which no prototype is available, the
integer promotions are performed on each argument (and arguments
of type float are converted to double). Thus, an "unsigned char"
argument will be converted to and passed as int (or unsigned int
on unusual implementations).

This rule for compatibility of function types is specified, in
C99, in section 6.7.5.3 paragraph 15:

For two function types to be compatible, both shall specify
compatible return types.125) Moreover, ... [if] one type
has a parameter type list and the other type is specified
by a function declarator that is not part of a function
definition and that contains an empty identifier list, the
parameter list shall not have an ellipsis terminator and
the type of each parameter shall be compatible with the
type that results from the application of the default
argument promotions.

It's a rather opaque paragraph, but I'm pretty sure that's what
it means.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jan 31 '07 #2
Charles Sullivan <cw******@triad.rr.comwrites:
I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};

int func1(<argument list>)
{
<blah-blah-blah1>
}

int func2(<argument list>)
{
<blah-blah-blah2>
}

I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?
I don't believe you've given us enough information to answer that.
Show us some actual code that exhibits the problem. You don't have to
post your actual code (which is probably too big to post); you can
just replace <other stuffwith, say, "int x;", and
"<blah-blah-blah11>" with nothing.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 31 '07 #3
"Charles Sullivan" <cw******@triad.rr.comwrote in message
news:pa****************************@triad.rr.com.. .
>I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};

int func1(<argument list>)
{
<blah-blah-blah1>
}

int func2(<argument list>)
{
<blah-blah-blah2>
}

I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?
The problem is probably here:
int (*myfunc)();
A modern compiler is going to demand that the input parameters (arguments)
to the function (as defined in the pointer type) be compatible with the
function prototype. I could make arguments based on full prototype linkage
and so on.

Just supply the argument list and I think you'll be OK.

--
David T. Ashley (dt*@e3ft.com)
http://www.e3ft.com (Consulting Home Page)
http://www.dtashley.com (Personal Home Page)
http://gpl.e3ft.com (GPL Publications and Projects)
Jan 31 '07 #4
Charles Sullivan wrote On 01/31/07 16:27,:
I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};

int func1(<argument list>)
{
<blah-blah-blah1>
}

int func2(<argument list>)
{
<blah-blah-blah2>
}

I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?
Ben Pfaff has explained the error; here are suggestions
for a few fixes.

If all the (<argument prototype>) lists are identical, that's
the easiest case: just change the myfunc declaration inside the
struct to

int (*myfunc)(<argument prototypes>);

and all will be well. ("Identical" in argument count and types;
argument names, if any, don't matter.)

If the prototypes for func1(), func2(), etc. are not the
same, it's a bit harder. In the initializer list, you need to
convert each function pointer to the expected type:

{<other stuff value>, (int(*)())func1},
{<other stuff value>, (int(*)())NULL},
{<other stuff value>, (int(*)())func2},

You could improve the readability by introducing a typedef for
the function pointer casts; also, the cast of NULL isn't really
needed.

But that's not all! At the point where you actually use
the function pointer to call the pointed-to function, you need
to convert it back to the defined type of that called function.
This means you need some way of figuring out what that type is
supposed to be, perhaps with a type code in the <other stuff>.
Then you could write something like

switch (myrecords[i].type) {
case ONE_INT:
result = ((int(*)(int))myrecords[i].myfunc)(42);
break;
case TWO_DOUBLES:
result = ((int(*)(double,double))myrecords[i].myfunc)
(42.0, sqrt(42.0));
break;
...

Again, typedefs might improve the readability.

--
Er*********@sun.com
Jan 31 '07 #5
Keith Thompson <ks***@mib.orgwrites:
Charles Sullivan <cw******@triad.rr.comwrites:
I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};
[snip]
I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?

I don't believe you've given us enough information to answer that.
Show us some actual code that exhibits the problem. You don't have to
post your actual code (which is probably too big to post); you can
just replace <other stuffwith, say, "int x;", and
"<blah-blah-blah11>" with nothing.
I think there was actually enough information to pinpoint the problem;
several other responders saw what I missed.

Posting actual code is still a good idea, though.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 31 '07 #6
On Wed, 31 Jan 2007 16:27:33 -0500, I wrote:
I define and initialize an array of structures like the following,
(where the <verbiage within angle bracketsis just meant to be
explanatory):

int func1(<argument prototypes>);
int func2(<argument prototypes>);

struct mystruct {
<other stuff>;
int (*myfunc)();
} myrecords[] = {
{<other stuff value>, func1},
{<other stuff value>, NULL },
{<other stuff value>, func2}
};

int func1(<argument list>)
{
<blah-blah-blah1>
}

int func2(<argument list>)
{
<blah-blah-blah2>
}

I've always believed this was legal code, and have used something
similar a few times in the past, but now when (<argument list>) is:
(unsigned char x1, unsigned char x2, unsigned char x3,
int *y1, unsigned int *y2, int *y3)

I get the compiler message:
"warning: initialization from incompatible pointer type"

What am I doing wrong?
Many thanks Ben, Keith, David and Eric!

Ben nailed it with his explanation of promoting (which also
clarifies some other unrelated cryptic compiler messages I've
gotten). Thanks Ben.

Keith: Yes, It's good to post actual code, but it can be complex
and confusing unless boiled down to the essentials. Of course I
don't always succeed in identifying the essentials. :-)

David and Eric: Thanks for the practical solutions which I will
keep in mind. In this _particular_ case the neatest approach
was to rewrite the functions to make all the arguments int or
int * and do my own conversion back and forth when I call them.

Thanks again guys - the expertise in this newsgroup has once more
restored my sanity!

Regards,
Charles Sullivan



Feb 1 '07 #7

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

Similar topics

3
by: Bruno van Dooren | last post by:
Hi All, i have some (3) different weird pointer problems that have me stumped. i suspect that the compiler behavior is correct because gcc shows the same results. ...
6
by: Edd Dawson | last post by:
Hi. I have a strange problem involving the passing of command line arguments to a C program I'm writing. I tried posting this in comp.programming yesterday but someone kindly suggested that I'd...
3
by: Timo | last post by:
I am trying to pass a pointer to an array of structures to function, but I have some problems. I am using MS Visual C++ 6.0, but I think this is more of a C-problem than Windows programming...
3
by: Thomas Christmann | last post by:
Hi! Sorry for the weird topic, I don't know how to describe it better... I have a little problem here I can't wrap my mind around. If I do: ------------------------------------- #define DWORD...
8
by: intrepid_dw | last post by:
Hello, all. I've created a C# dll that contains, among other things, two functions dealing with byte arrays. The first is a function that returns a byte array, and the other is intended to...
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
5
by: weidongtom | last post by:
Hi, I tried to implement the Universal Machine as described in http://www.boundvariable.org/task.shtml, and I managed to get one implemented (After looking at what other's have done.) But when I...
11
by: venkatagmail | last post by:
I have problem understanding pass by value and pass by reference and want to how how they are or appear in the memory: I had to get my basics right again. I create an array and try all possible...
49
by: Davy | last post by:
Hi all, I am writing a function, which return the pointer of the int. But it seems to be wrong. Any suggestion? int * get_p_t(int t) { return &t; } int main()
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: 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?
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

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.