Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Function declarations

Reply
Thread Tools

Function declarations

 
 
BartC
Guest
Posts: n/a
 
      09-28-2012
I have a C code generator that likes to insert lots of parentheses in type
declarations (rather than truly understand how they work).

But when declaring a function returning a pointer:

int (*fn) (void);

int (*fn) (void ) {return NULL;}

the prototype works, but not the definition (it's a syntax error). How do I
have to change the latter to make it compile?

Everywhere else the extra parentheses don't seem to be a problem.


Thanks.

--
Bartc.

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-28-2012
"BartC" <(E-Mail Removed)> writes:
> I have a C code generator that likes to insert lots of parentheses in type
> declarations (rather than truly understand how they work).
>
> But when declaring a function returning a pointer:
>
> int (*fn) (void);
>
> int (*fn) (void ) {return NULL;}
>
> the prototype works, but not the definition (it's a syntax error). How do I
> have to change the latter to make it compile?
>
> Everywhere else the extra parentheses don't seem to be a problem.


That's not a valid function definition.

Your first line declares an object `fn` of pointer-to-function type,
which is perfectly valid.

The declaration part of the function definition (the part outside
{...}) declares a pointer-to-function type. A function definition
has to declare something of function type, not pointer type.

You could drop the parentheses:

int fn(void) { return 0; }

Note that I've changed the return expression, since NULL is normally
used for pointers.

Or you might have something like this:

int func(void) { return 0; }
int (*fn)(void) = func;

I can't tell which of these would suit your purposes.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Heikki Kallasjoki
Guest
Posts: n/a
 
      09-28-2012
On 2012-09-28, BartC <(E-Mail Removed)> wrote:
> I have a C code generator that likes to insert lots of parentheses in type
> declarations (rather than truly understand how they work).
>
> But when declaring a function returning a pointer:
>
> int (*fn) (void);
>
> int (*fn) (void ) {return NULL;}
>
> the prototype works, but not the definition (it's a syntax error). How do I
> have to change the latter to make it compile?


That's not a function returning a pointer: that's a pointer to a
function (returning int):

$ cdecl
int (*fn) (void);
declare fn as pointer to function that expects (void) returning int;

int *fn(void) { ... } will (of course) work.


--
Heikki Kallasjoki
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-28-2012
"BartC" <(E-Mail Removed)> writes:

> I have a C code generator that likes to insert lots of parentheses in
> type declarations (rather than truly understand how they work).
>
> But when declaring a function returning a pointer:
>
> int (*fn) (void);


That's not what the above does. It declares (and, at file scope,
tentatively defines) a pointer to a function.

> int (*fn) (void ) {return NULL;}


Returning NULL is peculiar but fits with what you say you intended.

> the prototype works, but not the definition (it's a syntax error). How
> do I have to change the latter to make it compile?


The latter, just like the former, declares a pointer, not a function.
You'd make it work by giving it a suitable initialiser:

int (*fn)(void) = f; /* for some f of the right type, of course */

but it seems that you intended to write a prototype and a definition of
a function that returns a pointer:

int *fn(void);
int *fn(void) { return NULL; }

> Everywhere else the extra parentheses don't seem to be a problem.


They aren't a problem here either, it's just that you've mistaken what
they mean.

There *is* a symmetry problem with C's function definitions: you can use
a typedef of a function type to declare functions but not to define
them. For example, if you want to declare a whole bunch of functions of
the same type, it's easy:

typedef int binary_operator(int, int);

binary_operator add, sub, mul, div, rem, mod, exp;

and the typedef comes in hand if you have (as is likely) a table of
pointers to such functions. But when you come to define them, you can't
use the typedef name -- you have to repeat the types:

int add(int a, int b) { return a + b; }

It would be nice if you could use the typedef and add just the parameter
names. However, the "obvious" syntax is wrong:

binary_operator add(a, b) { return a + b; }

because binary_operator look like (well, is) the return type and not the
function type. You'd need a new form of function definition, maybe:

binary_operator add = (a, b) { return a + b; }

which, at least, looks like an initialiser. Far too fiddly to parse, I
imagine, and the use cases are too rare to register on the committee's
radar.

--
Ben.
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      09-28-2012


"BartC" <(E-Mail Removed)> wrote in message news:k43ulj$v03$(E-Mail Removed)...
> I have a C code generator that likes to insert lots of parentheses in type
> declarations (rather than truly understand how they work).


> int (*fn) (void);
>
> int (*fn) (void ) {return NULL;}


OK, the replies are telling me these are both wrong! For what I'd intended
anyway.

The parentheses I insert automatically are needed to distinguish between:

int *a[]; // array of pointer to int
int *(a[]); // also array of pointer to int
int (*a)[]; // pointer to array of int

The code generator isn't clever enough to insert only when necessary.

However, playing with CDECL, and using the last example above as return
value from the function (as I want to see how parentheses work when they are
actually needed), I ended up with:

int (*fn(void ))[];
int (*fn(void ))[] {return 0;};

This last example is especially intriguing; I've never seen "[]" between a
function parameter list and the opening "{" before!

What this telling me though, is the parameter list needs to be taken inside
the declaration and be attached to the name, so I will experiment with that.
Maybe I can get to keep my parentheses.

--
Bartc

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-28-2012
"BartC" <(E-Mail Removed)> writes:

> "BartC" <(E-Mail Removed)> wrote in message news:k43ulj$v03$(E-Mail Removed)...
>> I have a C code generator that likes to insert lots of parentheses
>> in type declarations (rather than truly understand how they work).

>
>> int (*fn) (void);
>>
>> int (*fn) (void ) {return NULL;}

>
> OK, the replies are telling me these are both wrong! For what I'd
> intended anyway.
>
> The parentheses I insert automatically are needed to distinguish between:
>
> int *a[]; // array of pointer to int
> int *(a[]); // also array of pointer to int
> int (*a)[]; // pointer to array of int
>
> The code generator isn't clever enough to insert only when necessary.


I don't think that will be a problem.

> However, playing with CDECL, and using the last example above as
> return value from the function (as I want to see how parentheses work
> when they are actually needed), I ended up with:
>
> int (*fn(void ))[];
> int (*fn(void ))[] {return 0;};
>
> This last example is especially intriguing; I've never seen "[]"
> between a function parameter list and the opening "{" before!
>
> What this telling me though, is the parameter list needs to be taken
> inside the declaration and be attached to the name, so I will
> experiment with that. Maybe I can get to keep my parentheses.


You can keep (or add) as many parentheses as you want but I suspect your
trouble is that you are adding them in a way that alters the intended
meaning.

The parameter list must be "syntactically attached" to the name but it
can be separated from it by redundant parentheses:

int f(void);
int (f)(void);
int ((f))(void);

are all the same. The rules for reading C types help here: you read
from the name outwards respecting balanced parentheses but otherwise
always reading to the right before reading to the left. You stop
reading to the right or to the left when you reach an opening or closing
bracket (or the end of declaration). In other words you read from the
inside out always finishing off a parenthesised part before moving on.
When you hit the ')' at the end of a parameter list, you can say "and
returning", otherwise just don't vocalise it:

int (*fn(void))[];
^ fn is a
^ function taking
^ no arguments
^ and returning
^ (silently change direction[1])
^ a pointer to
^ (silently change direction)
^ an array of
^ (silently change direction)
^ int

(This will look silly without a fixed-width font.)

Functions can't return array types but the syntax (and these rules) let
us know what that would look like. If at the point marked [1] we were
to see []s instead of ')' or ';' like this:

... *fn(void)[] ...

we'd have to say "and returning an array of".

--
Ben.
 
Reply With Quote
 
Agnos
Guest
Posts: n/a
 
      10-07-2012
BartC wrote:
> I have a C code generator that likes to insert lots of parentheses in
> type declarations (rather than truly understand how they work).
>
> But when declaring a function returning a pointer:
>
> int (*fn) (void);
>
> int (*fn) (void ) {return NULL;}
>
> the prototype works, but not the definition (it's a syntax error).
> How do I have to change the latter to make it compile?
>
> Everywhere else the extra parentheses don't seem to be a problem.
>


You worked for a BIG manufacturer, and now you are nothing but the
throw-away slag on the molten iron of the machines that you assembled?


 
Reply With Quote
 
Agnos
Guest
Posts: n/a
 
      10-07-2012
Keith Thompson wrote:

Who cares what he wrote? Look at his sig(!):

> Keith Thompson (The_Other_Keith) (E-Mail Removed)
> <http://www.ghoti.net/~kst>
> Will write code for food.
> "We must do something. This is something. Therefore, we must do this."
> -- Antony Jay and Jonathan Lynn, "Yes Minister"


As far as I care, until he resolves his issues, I ignore his other forays.


 
Reply With Quote
 
Agnos
Guest
Posts: n/a
 
      10-07-2012
Ben Bacarisse wrote:

Ha! You spelled his name wrong! It's Ben Briarcase, idiot.


 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      10-07-2012
On Oct 7, 6:34*am, "Agnos" <(E-Mail Removed)> wrote:
> Keith Thompson wrote:


> Who cares what he wrote? Look at his sig(!):
>
> > Keith Thompson (The_Other_Keith) (E-Mail Removed)
> > <http://www.ghoti.net/~kst>
> > * *Will write code for food.
> > "We must do something. *This is something. *Therefore, we must do this."
> > * *-- Antony Jay and Jonathan Lynn, "Yes Minister"

>
> As far as I care, until he resolves his issues, I ignore his other forays..


what? a couple of mildly funny quotes, one from an old UK comedy
program
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const in function declarations TechCrazy C++ 6 04-24-2005 09:13 PM
function declarations, global/within a function? Douglas C Programming 2 07-05-2004 08:54 PM
Function declarations/defaults Billy Patton C Programming 17 11-19-2003 02:32 AM
Mangled function type declarations? Marcus Lessard C Programming 1 10-17-2003 10:11 PM
Local function declarations Dave Theese C++ 1 09-05-2003 05:58 AM



Advertisments