[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Tinycc-devel Digest, Vol 103, Issue 1

From: Ben
Subject: Re: [Tinycc-devel] Tinycc-devel Digest, Vol 103, Issue 1
Date: Wed, 02 Nov 2011 20:32:18 +0000

On Wed, 2011-11-02 at 17:29 +0100, Robert Clausecker wrote:
> Am Mittwoch, den 02.11.2011, 12:00 -0400 schrieb Ben Bacarisse
> > > It seems that I discovered a bug in tcc. ANSI C allows declaration
> > of
> > > prototypes containing function pointers like this:
> > > 
> > >         void traverse(mystruct_t*, void(mycontent_t*));
> > > 
> > > tcc currently rejects this giving an error "')' expected". This
> > > equivalent prototype works:
> > > 
> > >         void traverse(mystruct_t*,void(*)(mycontent_t*));
> > > 
> > > Is this a bug or a feature?
> > 
> > The two prototypes are not equivalent.  The first is a syntax error
> > but
> > the second one is fine -- provided you wanted to pass a pointer to a
> > function that takes a mycontent_t pointer and returns nothing.
> I asked some folks on #c on freenode and they told me to tell you that
> section, paragraph 9 of the C89 standard specifies that this is
> allowed.

Yes, they are correct.  It's unusual to see such types in a prototype
but they are indeed valid.  Sad to say, I actually knew this, but for
some reason chose to forget about it.

>  (Why else would both gcc and clang allow the first declaration
> with or without the -std=c89 or -ansi flag?) Quote:
>         For each parameter declared with function or array type, its
>         type for these comparisons is the one that results from
>         conversion to a pointer type, as in $3.7.1.

C99 is the current standard, but it has similar wording.  It's been
split out into its own paragraph (p8 of and it now reads:

  "A declaration of a parameter as 'function returning type' shall
  be adjusted to 'pointer to function returning type', as in"

> I am not an expert on the C spec, but please have a look at it.
> Here is an easier testcase that compiles:
>         int foo(int,int,int(int,int));
>         int foo(int a,int b,int f(int,int)) { return f(a,b); }

It's also permitted via a typedef:

    typedef int func_type(int, int);
    int foo(int, int, func_type);

Personally, I always prefer to make the pointer explicit, but its
perfectly valid not to.

Ben Bacarisse

reply via email to

[Prev in Thread] Current Thread [Next in Thread]