Weird gcc behaviour with function pointer types

G

greg

In my quest to eliminate C compiler warnings from
Pyrex output, I've discovered some utterly bizarre
behaviour from gcc 3.3.

The following code:

void g(struct foo *x) {
}

void f(void) {
void (*h)(struct foo *);
h = g;
}

produces the following warning:

blarg.c: In function `f':
blarg.c:6: warning: assignment from incompatible pointer type

However, adding the following line at the top:

typedef struct foo Foo;

makes the warning go away. The mere *presence* of
the typedef is all that's needed -- it doesn't even
have to be used.

This looks like a bug in gcc to me -- what do people
think?
 
A

attn.steven.kuo

In my quest to eliminate C compiler warnings from
Pyrex output, I've discovered some utterly bizarre
behaviour from gcc 3.3.

The following code:

void g(struct foo *x) {
}

void f(void) {
void (*h)(struct foo *);
h = g;
}

produces the following warning:

blarg.c: In function `f':
blarg.c:6: warning: assignment from incompatible pointer type

However, adding the following line at the top:

typedef struct foo Foo;

makes the warning go away. The mere *presence* of
the typedef is all that's needed -- it doesn't even
have to be used.

This looks like a bug in gcc to me -- what do people
think?



Was there no (forward) declaration nor
definition of struct foo ahead of your functions?

I get no warnings with this:


struct foo; /* forward declaration */

void g(struct foo *x) {
}

void f(void) {
void (*h)(struct foo *);
h = g;
}


Using:

Target: powerpc-apple-darwin8
Configured with: /private/var/tmp/gcc/gcc-5026.obj~19/src/configure --
disable-checking --prefix=/usr --mandir=/share/man --enable-
languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^+.-]*$/s/
$/-4.0/ --with-gxx-include-dir=/include/gcc/darwin/4.0/c++ --
build=powerpc-apple-darwin8 --host=powerpc-apple-darwin8 --
target=powerpc-apple-darwin8
Thread model: posix

gcc version 4.0.0 (Apple Computer, Inc. build 5026)
 
R

Roger Miller

In my quest to eliminate C compiler warnings from
Pyrex output, I've discovered some utterly bizarre
behaviour from gcc 3.3.

The following code:

void g(struct foo *x) {
}

void f(void) {
void (*h)(struct foo *);
h = g;
}

produces the following warning:

blarg.c: In function `f':
blarg.c:6: warning: assignment from incompatible pointer type

However, adding the following line at the top:

typedef struct foo Foo;

makes the warning go away. The mere *presence* of
the typedef is all that's needed -- it doesn't even
have to be used.

This looks like a bug in gcc to me -- what do people
think?

If there is no outer declaration of struct foo visible to both
functions
gcc is right (it usually is when it comes to C technicalities). The
scope
of a struct declared inside a parameter list is limited to the
parameter
list itself, so the two "struct foo"s are technically different types.
Adding the typedef provides a common declaration of struct foo that is
shared by both functions. You don't really even need a typedef; a
global
declaration of just "struct foo;" should make the problem go away.

I would have expected gcc to also warn you about declaring a struct
inside
a parameter list. Did you get any warnings like that?
 

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,780
Messages
2,569,611
Members
45,269
Latest member
vinaykumar_nevatia23

Latest Threads

Top