By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,454 Members | 3,133 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,454 IT Pros & Developers. It's quick & easy.

* in front of function name?

P: n/a
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)

Mar 4 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
write is a pointer to functions which have four parameters, isn't it?

Mar 4 '06 #2

P: n/a
cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)


It means that return type is pointer.
--
My Personal Weblog:
http://spaces.msn.com/cyberisblue
Mar 4 '06 #3

P: n/a
cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)


The dec reads as:

write is a function pointer - and it should be set to point to a function
that returns an int, and that takes 4 parameters:

a struct inode *, a struct file *, a const char *, and an int
--
==============
*Not a pedant*
==============
Mar 4 '06 #4

P: n/a
yong wrote:
cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)


It means that return type is pointer.


No it does not. (That would've been: int *write(/* params */);)

The other reply (which didn't quote context) was right. It declares
`write` as pointer to function with 4 parameters as described above.

Consider using `cdecl`.

--
BR, Vladimir

Beware of a dark-haired man with a loud tie.

Mar 4 '06 #5

P: n/a
Vladimir S. Oka wrote:
yong wrote:
cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)

It means that return type is pointer.


No it does not. (That would've been: int *write(/* params */);)

The other reply (which didn't quote context) was right. It declares
`write` as pointer to function with 4 parameters as described above.


Which returns an `int`.
Consider using `cdecl`.


I should have pasted it's output in the first place. :-/

--
BR, Vladimir

She always believed in the old adage -- leave them while you're looking
good.
-- Anita Loos, "Gentlemen Prefer Blondes"

Mar 4 '06 #6

P: n/a
yong wrote:
cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)


It means that return type is pointer.


No.

--
==============
*Not a pedant*
==============
Mar 4 '06 #7

P: n/a
cm****@hotmail.com writes:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);


This does not declare a function; it declares a /pointer/ to a
function. write is a pointer to a function that takes four arguments
and returns int.
Mar 4 '06 #8

P: n/a

cm****@hotmail.com wrote:
Hi
Why put * in front of the function name in the declaration?

int (*write)(struct inode *, struct file *, const char *, int);

thanks
from Peter (cm****@hotmail.com)


This declares write as a pointer to a function taking 4 arguments and
returning an int. As to *why* you want to do this, there are a couple
of reasons:

1. You can pass a pointer to a function as a parameter to another
function; this is known as a callback, and is useful in a number of
contexts. The canonical example is the qsort() library function, which
can sort 1D arrays elements of any type. Here's how it's used:

/*
* prototype for qsort() as found in stdlib.h
*
* void qsort(void *base, size_t count, size_t size, int (*cmp)(const
void *, const void *));
*/
#include <stdlib.h>
#include <string.h>

int compareInts(const void *arg1, const void *arg2)
{
int *a = arg1;
int *b = arg2;

if (*a < *b)
return -1;
else if (*a > *b)
return 1;
else
return 0;
}

int compareMyStructs(const void *arg1, const void *arg2)
{
MyStruct *a = arg1;
MyStruct *b = arg2;

/*
* Assume the key value for MyStruct is a character string
*/
char *key1 = a->getKey();
char *key2 = b->getKey();

if (strcmp(a, b) < 0)
return -1;
else if (strcmp(a, b) > 0)
return 1;
else
return 0;
}

int main(void)
{
int iArr[20];
MyStruct sArr[30];

...

qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0],
compareInts);
qsort(sArr, sizeof sArr/sizeof sArr[0], sizeof sArr[0],
compareMyStructs);

...

return 0;
}

The signal() library function does something similar; you pass it a
pointer to a function you want executed every time a particular signal
is raised:

void handleInterrupt(sig_atomic_t sig)
{
gInterrupt = 1;
}

int main(void)
{
signal(SIGINT, handleInterrupt);
...
}

2. With function pointers, you can implement a primitive form of
polymorphism, where you can refer to a generic "write" function in your
logic that resolves to one of several different functions based at
runtime. One project I did many years ago involved writing parsers for
a set of data files. I created a lookup table that was keyed by file
type and contained pointers to the actual parse functions, and a
function that performed the actual lookup. It was structured somewhat
like this:

extern void parseGraFile(char *fileName);
extern void parsePWaveFile(char *fileName);
....

struct parseTable {
char *fileType;
void (*parse)(char *fileName);
};

static struct parseTable theTable[] = {{"GRA", parseGraFile}, {"PWV",
parsePWaveFile}, ...}

/*
* The following declaration reads as "lookup is a function returning a
pointer to a function
* taking a char * parameter and returning void"
*/
void (*lookup(char *fileType))(char *fileName)
{
size_t tableCount = sizeof theTable/sizeof theTable[0];
size_t i;

for (i = 0; i < tableCount; i++)
{
if (!strcmp(fileType, theTable[i].fileType))
return theTable[i].parse;
}

return NULL;
}

char *typeFromName(char *fileName)
{
/* parse the file type out of the file name and return it */
}

void parseFiles(const char **fileList, const size_t numFiles)
{
size_t i;

for (i = 0; i < numFiles; i++)
{
char *type;
void (*parser)(char *fileName);

type = typeFromName(fileList[i]);
parser = lookup(type);
if (parser)
{
parser(fileList[i]);
}
else
{
/* handle unrecognized file type */
}
}
}

Basically, the right parsing function would be called based on the file
type. The advantage to this approach is that you don't have to hack
the main application logic every time a new file type is added or
removed; you just update the lookup table.

Mar 5 '06 #9

P: n/a
On 5 Mar 2006 06:25:56 -0800, "John Bode" <jo*******@my-deja.com>
wrote:
<snip>
This declares write as a pointer to a function taking 4 arguments and
returning an int. As to *why* you want to do this, there are a couple
of reasons:

1. You can pass a pointer to a function as a parameter to another
function; this is known as a callback, and is useful in a number of
contexts. The canonical example is the qsort() library function, which
can sort 1D arrays elements of any type. Here's how it's used:

/*
* prototype for qsort() as found in stdlib.h
*
* void qsort(void *base, size_t count, size_t size, int (*cmp)(const
void *, const void *));
*/
#include <stdlib.h>
#include <string.h>

int compareInts(const void *arg1, const void *arg2)
{
int *a = arg1;
int *b = arg2;
These need to be const int * to avoid a constraint violation and
diagnostic. And should be anyway, since a comparison routine should
not be changing the things it compares, at least not simple things.

<snip> int compareMyStructs(const void *arg1, const void *arg2)
{
MyStruct *a = arg1;
MyStruct *b = arg2;
ditto.
/*
* Assume the key value for MyStruct is a character string
*/
char *key1 = a->getKey();
char *key2 = b->getKey();
Perhaps ditto. And while it is certainly possible to have function
pointers in a struct, unless they vary, it would be more common to
have something more like:
const char *key1 = MyStruct_getKey (a); /* etc. */

Or even:
/*unconst*/ char key1 [KEY_SIZE], ...
MyStruct_getKey (a, key1); ...
if (strcmp(a, b) < 0)
return -1;
else if (strcmp(a, b) > 0)
return 1;
else
return 0;


The qsort comparator is only required to return <0/0/>0, not
specifically -1/0/+1, so you can just return strcmp (a, b).

<snip rest>

- David.Thompson1 at worldnet.att.net
Mar 20 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.