473,880 Members | 1,880 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2216
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[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof 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_Keit h) 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)(<argu ment 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))m yrecords[i].myfunc)(42);
break;
case TWO_DOUBLES:
result = ((int(*)(double ,double))myreco rds[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.orgw rites:
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_Keit h) 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
2366
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. ---------------------------------------------- //example 1: typedef int t_Array; int main(int argc, char* argv)
6
2939
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 have better luck here. So here goes! My program ignores any command line arguments, or at least it's supposed to. However, when I pass any command line arguments to the program, the behaviour of one of the functions changes mysteriously. I have...
3
5092
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 specific. Here is the relevant part of my code. typedef struct { int iControlID; char controlTxt;
3
2089
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 unsigned long #include <stdio.h> #include <malloc.h>
8
10728
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 receive a byte array as one of its parameters. The project is marked for COM interop, and that all proceeds normally. When I reference the type library in the VB6 project, and write the code to call the function that returns the byte array, it works
39
19673
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) What's the difference between these 3 statements: (i) memcpy(&b, &KoefD, n); // this works somewhere in my code
5
2566
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 use to run a UM program, I kept on getting error messages. I have used someone else's implementation and it runs fine. I have compared my code with other's and I still can't figure it out what's wrong with mine. So please help me out, after 3...
11
3373
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 ways of passing an array. In the following code, fun1(int a1) - same as fun1(int* a1) - where both are of the type passed by reference. Inside this function, another pointer a1 is created whose address &a1 is different from that of the passed...
49
2753
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
9925
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11089
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10713
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10809
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9550
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7948
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5972
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4595
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3219
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.