The gcc C compiler doesn't seem to be following the traditional "right-then-left" rule when compiling function pointer prototypes.
For example, gcc properly considers this to be a valid prototype: int (*count)( demo_counter * self, int count_amt ); , but it does not seem to recognize that the following is also a valid prototype: int count * ( demo_counter * self, int count_amt ); Following the traditional "right-then-left" rule, BOTH of these should be parsed as: "count is a pointer to a function which accepts a demo_counter pointer and an int and returns an int.". But the second one results in a compilation error with gcc. I'm sorry, but I have no idea what "Host triplet", "Target triplet" or "Build triplet" might possibly mean. However, per your instructions, here is some further information: * I noticed the bug while working on Windows XP, service pack 3, using the Cygwin gcc compiler. I have not tried to reproduce it on other platforms or with other compilers. * Output from the compiler, including gcc version information and compiler flags, appears below: C:\f_p_compile>echo %PROCESSOR_IDENTIFIER% x86 Family 6 Model 15 Stepping 10, GenuineIntel C:\f_p_compile>make -f makefile gcc_version gcc --version gcc (GCC) 4.3.2 20080827 (beta) 2 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. C:\f_p_compile>make -f makefile demo_counter_demo gcc -Wall -g -std=c99 -save-temps -o demo_counter.o -c demo_counter.c In file included from demo_counter.c:2: demo_counter.h:17: error: expected ':', ',', ';', '}' or '__attribute__' before '*' token demo_counter.c: In function 'demo_counter_constructor': demo_counter.c:17: error: 'demo_counter' has no member named 'count' make: *** [demo_counter.o] Error 1 C:\f_p_compile> * the .i file fills the remainder of this description: # 1 "demo_counter.c" # 1 "/cygdrive/c/Documents and Settings/djones/Desktop/d_string/f_p_compile//" # 1 "<built-in>" # 1 "<command-line>" # 1 "demo_counter.c" # 1 "demo_counter.h" 1 # 10 "demo_counter.h" typedef struct demo_counter_proto demo_counter; struct demo_counter_proto { int m_count; void (*destroy)( demo_counter *); int count * ( demo_counter * self, int count_amt ); }; demo_counter * demo_counter_constructor(); # 2 "demo_counter.c" 2 # 1 "/usr/include/stdlib.h" 1 3 4 # 10 "/usr/include/stdlib.h" 3 4 # 1 "/usr/include/_ansi.h" 1 3 4 # 15 "/usr/include/_ansi.h" 3 4 # 1 "/usr/include/newlib.h" 1 3 4 # 16 "/usr/include/_ansi.h" 2 3 4 # 1 "/usr/include/sys/config.h" 1 3 4 # 1 "/usr/include/machine/ieeefp.h" 1 3 4 # 5 "/usr/include/sys/config.h" 2 3 4 # 167 "/usr/include/sys/config.h" 3 4 # 1 "/usr/include/cygwin/config.h" 1 3 4 # 168 "/usr/include/sys/config.h" 2 3 4 # 17 "/usr/include/_ansi.h" 2 3 4 # 11 "/usr/include/stdlib.h" 2 3 4 # 1 "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/stddef.h" 1 3 4 # 214 "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/stddef.h" 3 4 typedef unsigned int size_t; # 326 "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/stddef.h" 3 4 typedef short unsigned int wchar_t; # 15 "/usr/include/stdlib.h" 2 3 4 # 1 "/usr/include/sys/reent.h" 1 3 4 # 13 "/usr/include/sys/reent.h" 3 4 # 1 "/usr/include/_ansi.h" 1 3 4 # 14 "/usr/include/sys/reent.h" 2 3 4 # 1 "/usr/include/sys/_types.h" 1 3 4 # 12 "/usr/include/sys/_types.h" 3 4 # 1 "/usr/include/sys/lock.h" 1 3 4 # 14 "/usr/include/sys/lock.h" 3 4 typedef void *_LOCK_T; # 44 "/usr/include/sys/lock.h" 3 4 void __cygwin_lock_init(_LOCK_T *); void __cygwin_lock_init_recursive(_LOCK_T *); void __cygwin_lock_fini(_LOCK_T *); void __cygwin_lock_lock(_LOCK_T *); int __cygwin_lock_trylock(_LOCK_T *); void __cygwin_lock_unlock(_LOCK_T *); # 13 "/usr/include/sys/_types.h" 2 3 4 typedef long _off_t; __extension__ typedef long long _off64_t; typedef int _ssize_t; # 1 "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/stddef.h" 1 3 4 # 355 "/usr/lib/gcc/i686-pc-cygwin/4.3.2/include/stddef.h" 3 4 typedef unsigned int wint_t; # 25 "/usr/include/sys/_types.h" 2 3 4 typedef struct { int __count; union { wint_t __wch; unsigned char __wchb[4]; } __value; } _mbstate_t; typedef _LOCK_T _flock_t; typedef void *_iconv_t; # 15 "/usr/include/sys/reent.h" 2 3 4 typedef unsigned long __ULong; # 35 "/usr/include/sys/reent.h" 3 4 struct _reent; struct _Bigint { struct _Bigint *_next; int _k, _maxwds, _sign, _wds; __ULong _x[1]; }; struct __tm { int __tm_sec; int __tm_min; int __tm_hour; int __tm_mday; int __tm_mon; int __tm_year; int __tm_wday; int __tm_yday; int __tm_isdst; }; struct _on_exit_args { void * _fnargs[32]; void * _dso_handle[32]; __ULong _fntypes; __ULong _is_cxa; }; # 87 "/usr/include/sys/reent.h" 3 4 struct _atexit { struct _atexit *_next; int _ind; void (*_fns[32])(void); struct _on_exit_args _on_exit_args; }; # 103 "/usr/include/sys/reent.h" 3 4 struct __sbuf { unsigned char *_base; int _size; }; typedef long _fpos_t; typedef _off64_t _fpos64_t; # 168 "/usr/include/sys/reent.h" 3 4 struct __sFILE { unsigned char *_p; int _r; int _w; short _flags; short _file; struct __sbuf _bf; int _lbfsize; void * _cookie; _ssize_t __attribute__((__cdecl__)) (*_read) (struct _reent *, void *, char *, int); _ssize_t __attribute__((__cdecl__)) (*_write) (struct _reent *, void *, const char *, int); _fpos_t __attribute__((__cdecl__)) (*_seek) (struct _reent *, void *, _fpos_t, int); int __attribute__((__cdecl__)) (*_close) (struct _reent *, void *); struct __sbuf _ub; unsigned char *_up; int _ur; unsigned char _ubuf[3]; unsigned char _nbuf[1]; struct __sbuf _lb; int _blksize; int _offset; struct _reent *_data; _flock_t _lock; }; struct __sFILE64 { unsigned char *_p; int _r; int _w; short _flags; short _file; struct __sbuf _bf; int _lbfsize; struct _reent *_data; void * _cookie; _ssize_t __attribute__((__cdecl__)) (*_read) (struct _reent *, void *, char *, int); _ssize_t __attribute__((__cdecl__)) (*_write) (struct _reent *, void *, const char *, int); _fpos_t __attribute__((__cdecl__)) (*_seek) (struct _reent *, void *, _fpos_t, int); int __attribute__((__cdecl__)) (*_close) (struct _reent *, void *); struct __sbuf _ub; unsigned char *_up; int _ur; unsigned char _ubuf[3]; unsigned char _nbuf[1]; struct __sbuf _lb; int _blksize; int _flags2; _off64_t _offset; _fpos64_t __attribute__((__cdecl__)) (*_seek64) (struct _reent *, void *, _fpos64_t, int); _flock_t _lock; }; typedef struct __sFILE64 __FILE; struct _glue { struct _glue *_next; int _niobs; __FILE *_iobs; }; # 294 "/usr/include/sys/reent.h" 3 4 struct _rand48 { unsigned short _seed[3]; unsigned short _mult[3]; unsigned short _add; }; # 569 "/usr/include/sys/reent.h" 3 4 struct _reent { int _errno; __FILE *_stdin, *_stdout, *_stderr; int _inc; char _emergency[25]; int _current_category; const char *_current_locale; int __sdidinit; void __attribute__((__cdecl__)) (*__cleanup) (struct _reent *); struct _Bigint *_result; int _result_k; struct _Bigint *_p5s; struct _Bigint **_freelist; int _cvtlen; char *_cvtbuf; union { struct { unsigned int _unused_rand; char * _strtok_last; char _asctime_buf[26]; struct __tm _localtime_buf; int _gamma_signgam; __extension__ unsigned long long _rand_next; struct _rand48 _r48; _mbstate_t _mblen_state; _mbstate_t _mbtowc_state; _mbstate_t _wctomb_state; char _l64a_buf[8]; char _signal_buf[24]; int _getdate_err; _mbstate_t _mbrlen_state; _mbstate_t _mbrtowc_state; _mbstate_t _mbsrtowcs_state; _mbstate_t _wcrtomb_state; _mbstate_t _wcsrtombs_state; } _reent; struct { unsigned char * _nextf[30]; unsigned int _nmalloc[30]; } _unused; } _new; struct _atexit *_atexit; struct _atexit _atexit0; void (**(_sig_func))(int); struct _glue __sglue; __FILE __sf[3]; }; # 803 "/usr/include/sys/reent.h" 3 4 extern struct _reent *_impure_ptr ; extern struct _reent *const _global_impure_ptr ; void _reclaim_reent (struct _reent *); struct _reent * __attribute__((__cdecl__)) __getreent (void); # 17 "/usr/include/stdlib.h" 2 3 4 # 1 "/usr/include/machine/stdlib.h" 1 3 4 # 17 "/usr/include/machine/stdlib.h" 3 4 char *mkdtemp (char *); # 18 "/usr/include/stdlib.h" 2 3 4 # 1 "/usr/include/cygwin/stdlib.h" 1 3 4 # 14 "/usr/include/cygwin/stdlib.h" 3 4 # 1 "/usr/include/cygwin/wait.h" 1 3 4 # 15 "/usr/include/cygwin/stdlib.h" 2 3 4 const char *getprogname (void); void setprogname (const char *); # 24 "/usr/include/stdlib.h" 2 3 4 typedef struct { int quot; int rem; } div_t; typedef struct { long quot; long rem; } ldiv_t; # 57 "/usr/include/stdlib.h" 3 4 extern __attribute__((dllimport)) int __mb_cur_max; void __attribute__((__cdecl__)) abort (void) __attribute__ ((noreturn)); int __attribute__((__cdecl__)) abs (int); int __attribute__((__cdecl__)) atexit (void (*__func)(void)); double __attribute__((__cdecl__)) atof (const char *__nptr); int __attribute__((__cdecl__)) atoi (const char *__nptr); int __attribute__((__cdecl__)) _atoi_r (struct _reent *, const char *__nptr); long __attribute__((__cdecl__)) atol (const char *__nptr); long __attribute__((__cdecl__)) _atol_r (struct _reent *, const char *__nptr); void * __attribute__((__cdecl__)) bsearch (const void * __key, const void * __base, size_t __nmemb, size_t __size, int (* __attribute__((__cdecl__)) _compar) (const void *, const void *)); void * __attribute__((__cdecl__)) calloc (size_t __nmemb, size_t __size); div_t __attribute__((__cdecl__)) div (int __numer, int __denom); void __attribute__((__cdecl__)) exit (int __status) __attribute__ ((noreturn)); void __attribute__((__cdecl__)) free (void *); char * __attribute__((__cdecl__)) getenv (const char *__string); char * __attribute__((__cdecl__)) _getenv_r (struct _reent *, const char *__string); char * __attribute__((__cdecl__)) _findenv (const char *, int *); char * __attribute__((__cdecl__)) _findenv_r (struct _reent *, const char *, int *); long __attribute__((__cdecl__)) labs (long); ldiv_t __attribute__((__cdecl__)) ldiv (long __numer, long __denom); void * __attribute__((__cdecl__)) malloc (size_t __size); int __attribute__((__cdecl__)) mblen (const char *, size_t); int __attribute__((__cdecl__)) _mblen_r (struct _reent *, const char *, size_t, _mbstate_t *); int __attribute__((__cdecl__)) mbtowc (wchar_t *, const char *, size_t); int __attribute__((__cdecl__)) _mbtowc_r (struct _reent *, wchar_t *, const char *, size_t, _mbstate_t *); int __attribute__((__cdecl__)) wctomb (char *, wchar_t); int __attribute__((__cdecl__)) _wctomb_r (struct _reent *, char *, wchar_t, _mbstate_t *); size_t __attribute__((__cdecl__)) mbstowcs (wchar_t *, const char *, size_t); size_t __attribute__((__cdecl__)) _mbstowcs_r (struct _reent *, wchar_t *, const char *, size_t, _mbstate_t *); size_t __attribute__((__cdecl__)) wcstombs (char *, const wchar_t *, size_t); size_t __attribute__((__cdecl__)) _wcstombs_r (struct _reent *, char *, const wchar_t *, size_t, _mbstate_t *); void __attribute__((__cdecl__)) qsort (void * __base, size_t __nmemb, size_t __size, int(*_compar)(const void *, const void *)); int __attribute__((__cdecl__)) rand (void); void * __attribute__((__cdecl__)) realloc (void * __r, size_t __size); void __attribute__((__cdecl__)) srand (unsigned __seed); double __attribute__((__cdecl__)) strtod (const char *__n, char **__end_PTR); double __attribute__((__cdecl__)) _strtod_r (struct _reent *,const char *__n, char **__end_PTR); float __attribute__((__cdecl__)) strtof (const char *__n, char **__end_PTR); long __attribute__((__cdecl__)) strtol (const char *__n, char **__end_PTR, int __base); long __attribute__((__cdecl__)) _strtol_r (struct _reent *,const char *__n, char **__end_PTR, int __base); unsigned long __attribute__((__cdecl__)) strtoul (const char *__n, char **__end_PTR, int __base); unsigned long __attribute__((__cdecl__)) _strtoul_r (struct _reent *,const char *__n, char **__end_PTR, int __base); int __attribute__((__cdecl__)) system (const char *__string); # 183 "/usr/include/stdlib.h" 3 4 char * __attribute__((__cdecl__)) _dtoa_r (struct _reent *, double, int, int, int *, int*, char**); int __attribute__((__cdecl__)) _system_r (struct _reent *, const char *); void __attribute__((__cdecl__)) __eprintf (const char *, const char *, unsigned int, const char *); # 5 "demo_counter.c" 2 static void demo_counter_destroy( demo_counter * self ); static int demo_counter_count( demo_counter * self, int count_amt ); demo_counter * demo_counter_constructor() { demo_counter * p_fresh = malloc( sizeof( demo_counter ) ); if ( 0 != p_fresh ) { p_fresh->m_count = 0; p_fresh->destroy = demo_counter_destroy; p_fresh->count = demo_counter_count; } return p_fresh; } static void demo_counter_destroy( demo_counter * self ) { free( self ); } static int demo_counter_count( demo_counter * self, int count_amt ) { self->m_count += count_amt; return self->m_count; } -- Summary: not following "right-then-left" rule when compiling function pointers Product: gcc Version: 4.3.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dj2con at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40627