Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Function declarations (http://www.velocityreviews.com/forums/t952781-function-declarations.html)

BartC 09-28-2012 10:35 AM

Function declarations
 
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.


Keith Thompson 09-28-2012 10:59 AM

Re: Function declarations
 
"BartC" <bc@freeuk.com> 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) kst-u@mib.org <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"

Heikki Kallasjoki 09-28-2012 11:05 AM

Re: Function declarations
 
On 2012-09-28, BartC <bc@freeuk.com> 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

Ben Bacarisse 09-28-2012 11:27 AM

Re: Function declarations
 
"BartC" <bc@freeuk.com> 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.

BartC 09-28-2012 11:37 AM

Re: Function declarations
 


"BartC" <bc@freeuk.com> wrote in message news:k43ulj$v03$1@dont-email.me...
> 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


Ben Bacarisse 09-28-2012 12:21 PM

Re: Function declarations
 
"BartC" <bc@freeuk.com> writes:

> "BartC" <bc@freeuk.com> wrote in message news:k43ulj$v03$1@dont-email.me...
>> 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.

Agnos 10-07-2012 05:31 AM

Re: Function declarations
 
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?



Agnos 10-07-2012 05:34 AM

Re: Function declarations
 
Keith Thompson wrote:

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

> Keith Thompson (The_Other_Keith) kst-u@mib.org
> <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.



Agnos 10-07-2012 05:36 AM

Re: Function declarations
 
Ben Bacarisse wrote:

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



Nick Keighley 10-07-2012 09:23 AM

Re: Function declarations
 
On Oct 7, 6:34*am, "Agnos" <realthan...@myhigh.com> wrote:
> Keith Thompson wrote:


> Who cares what he wrote? Look at his sig(!):
>
> > Keith Thompson (The_Other_Keith) ks...@mib.org
> > <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


All times are GMT. The time now is 07:10 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57