regarding typedef

Y

yang__lee

Hi,

You all know typedef

typedef struct g
{
int a;
int b;
} google;

typedef google (*google)

google fl1;

fl1->a=10;
fl1->b=20;

see struct google was just a structure and was not a pointer
by using typedef we can change its name.

so after typedef google (*google); , why google variables are acting
like pointers.

Please help me in this.

thanks

lee
 
V

Vladimir S. Oka

(e-mail address removed) opined:
Hi,

You all know typedef

typedef struct g
{
int a;
int b;
} google;

typedef google (*google)

google fl1;

fl1->a=10;
fl1->b=20;

see struct google was just a structure and was not a pointer
by using typedef we can change its name.

so after typedef google (*google); , why google variables are acting
like pointers.

After that, `google` variables can't act like anything, as that line is
illegal. You can't re-use names like that. Try:

typedef struct g
{
int a;
int b;
} goog;

typedef goog* google;

google fl1;

Also, your use of parentheses is misleading. Have a look above, and
into your textbook. It declares a type that is a pointer to a `struct`
of type `goog`. All should be clear now.

--
BR, Vladimir

*** NEWSFLASH ***
Russian tanks steamrolling through New Jersey!!!!
Details at eleven!
 
J

Jordan Abel

(e-mail address removed) opined:


After that, `google` variables can't act like anything, as that line
is illegal. You can't re-use names like that. Try:
typedef struct g
{
int a;
int b;
}
* google;

I think is closer to what he intends.
Also, your use of parentheses is misleading.

Why? That's where the parentheses would go, if you were to put them
anywhere.
 
V

Vladimir S. Oka

Jordan Abel opined:
* google;

I think is closer to what he intends.


Why? That's where the parentheses would go, if you were to put them
anywhere.

Quite right, on both counts. I blame it on too many googles in the OP.
 
S

santosh

Hi,

You all know typedef

typedef struct g
{
int a;
int b;
} google;

typedef google (*google)

google fl1;

fl1->a=10;
fl1->b=20;

see struct google was just a structure and was not a pointer
by using typedef we can change its name.

so after typedef google (*google); , why google variables are acting
like pointers.

Please help me in this.

Apart from what the others say also read the following thread:
http://groups.google.com/group/comp...60001/ec35ae36c1b46ac4?hl=en#ec35ae36c1b46ac4
 
O

osmium

You all know typedef

typedef struct g
{
int a;
int b;
} google;

typedef google (*google)

google fl1;

fl1->a=10;
fl1->b=20;

see struct google was just a structure and was not a pointer
by using typedef we can change its name.

so after typedef google (*google); , why google variables are acting
like pointers.

Please help me in this.

You haven't taken the most elementary steps to help yourself.

It is a good idea, particularly when you are in unfamiliar waters, to give
different names to different things. It helps the thinking process
enormously.
 
Y

yang__lee

Hi,

Following thing is confusing to me..
Its not clear to me..


typedef int (*MyFunctionP)();

typedef struct
{
MyFunctionP myFuncP;
void *mdlDescP;
} neutral;


I am typedefing the int to a pointer to a function.
How can a int is involving with a function..
what is happening here.. please tell me.

thanks
lee.
 
K

Keith Thompson

Following thing is confusing to me..
Its not clear to me..


typedef int (*MyFunctionP)();

typedef struct
{
MyFunctionP myFuncP;
void *mdlDescP;
} neutral;


I am typedefing the int to a pointer to a function.
How can a int is involving with a function..
what is happening here.. please tell me.

Please don't top-post. See <http://www.caliburn.nl/topposting.html>.

The declaration doesn't typedef "int" to anything. It creates a
typedef called "MyFunctionP", which becomes an alias for the type
"int (*)()", or "pointer to function returning int".
 
B

Ben C

Hi,

Following thing is confusing to me..
Its not clear to me..

typedef int (*MyFunctionP)();

typedef struct
{
MyFunctionP myFuncP;
void *mdlDescP;
} neutral;


I am typedefing the int to a pointer to a function.

It looks like that, but actually you're typedeffing MyFunctionP to be a
pointer to a function returning int.
How can a int is involving with a function..
what is happening here.. please tell me.

It's just rather difficult syntax. I've never met anyone who didn't find
function types in C a bit hard to read.

Think about this:

Some people write:

int* p;

which you can read as "p is a pointer to int", as if int* were a type.

Another style is:

int *p;

which you can read as "p is a pointer, and *p is an int".

Well you can read this:

int (*fn)(int) = f;

as "fn is a pointer, and *fn is a function that takes an int and return
an int"

typedefs work just like declarations. Practical advice for function
pointers is always typedef them and if you can't remember the syntax
copy one from somewhere (you'll usually find one in man qsort).

I'd appreciate a better explanation of function type syntax myself. I
think I've just got used to them rather than ever understood them.
 
C

Chris Torek

... you can read this:

int (*fn)(int) = f;

as "fn is a pointer, and *fn is a function that takes an int and return
an int". ...
I'd appreciate a better explanation of function type syntax myself. I
think I've just got used to them rather than ever understood them.

The above is exactly the right description.

Dennis has said that the rule for C is "declaration mirrors use".
If one uses (*p)[3] to access one "double" object, then:

double (*p)[N];

is probably the actual declaration (and N is at least 4), giving
p the type "pointer to array N of double". Thus *p has type
"array N of double", and (*p)[3] has type "double".

Of course, (*p) and (p[0]) do the same thing in actual code, so
it is possible to write p[0][3] instead of (*p)[3]. But that
would imply a declaration like:

double p[M][N];

for some integral constants M > 0 and N > 3. Hence, "declaration
mirrors use" only if you happen to use the same format as the
declaration. This also causes confusion with function pointers:

#include <math.h>
...
double result, argument;
double (*fp)(double);

if (use_sine)
fp = sin;
else /* use cosine */
fp = cos;
...
result = (*fp)(argument);

As with arrays and pointers, function names "decay" to pointers to
those functions in most contexts. Here (*fp) "follows the pointer"
in "fp" to the appropriate function (sin or cos), then "un-follows"
it (via "decay") to get the pointer, and only then does the call,
using the pointer. So we can drop the asterisk, and write:

result = fp(argument);

This is the same technique (though a different end-point, as it
were) that we use when we write:

double some_table[SOME_SIZE];
double *dp;
...
dp = some_table;

instead of "dp = &some_table[0]".

Probably the most confusing of all C's type syntaxes is that for
casts (and, correspondingly, unnamed prototype arguments). To form
a proper cast, start by writing a declaration for a variable of
the given type. Let us tackle a tough one: a pointer to a function
that handles a signal. ANSI/ISO C says that a signal function
receives one "int" (the signal number) and returns "void". So the
function itself might look like:

void handle_signal(int sig) {
... some code here ...
}

A pointer to such a function has type:

pointer to function (int) returning void

which is declared as:

void (*fp)(int);

To turn this into a cast, start with the declaration and remove
the name:

void (*)(int)

Then just add parentheses around the whole thing, giving:

(void (*)(int))

Of course, you have to cast some actual value, such as 0. Add
parentheses to that "just in case", and you get a typical definition
for SIG_DFL:

#define SIG_DFL ((void (*)(int))0)

In a function prototype, the arguments can have names, or omit them:

double cos(double argument);
double sin(double);

In an implementation header -- one provided by an implementor -- the
implementor has to be careful not to use a user's name. Imagine
the troubles that occur if the user writes, for instance:

#define i "me, myself"
#include <stdlib.h>

and <stdlib.h> says something like:

int abs(int i);

which then expands to:

int abs(int "me, myself");

Hence, if you look at actual implementor's headers, they tend to use
either:

int abs(int); /* no identifier = no chance for the user to #define it */

or:

int abs(int __i); /* __ prefix is reserved, keep your hands off! */

So consider signal(), again. Its first argument is an "int",
the signal number; its second argument is a pointer to a signal
function.

We already came up with the spelling for the type "pointer to
function taking one int and returning void":

void (*)(int)

So signal's two arguments, using no names, are:

____ int, void (*)(int) ____

(where ____ represents the blanks to fill in later).

However, signal's return value has the same type as its second
argument: "pointer to function taking one int and returning void".
To spell *that*, without using a typedef, we have to declare
signal as:

void (*signal( ____ ))(int);

where ____ represents "the arguments to the actual function" (again,
"blanks to fill in later"). The parentheses around (*signal( ____ ))
are required to force the "*" to bind to the "signal(int)" part,
and not to the "void" part.

Finally, we can drop in the arguments, which we already worked out:

void (*signal(int, void (*)(int)))(int);

and we have a correct prototype for signal(), using no names. If
we are playing implementor -- writing <signal.h> -- and choose to
put in names, we have to use our (implementor) reserved names with
double underscores or similar, and write:

void (*signal(int __sig, void (*__func)(int)))(int);

As an ordinary (non-implementor) C programmer, of course, we would
have to *avoid* the double-underscore names.

This is a lot easier with a typedef, in part because signal's second
parameter -- "pointer to function taking int and returning void"
-- has the *same* type as its return value. So one typedef,
for "pointer to function taking int and returning void", removes
all the hair:

typedef void (*signal_function_pointer)(int);

signal_function_pointer signal(int sig, signal_function_pointer func);

Of course, if we put on our Implementor Hats and write a *new*
<signal.h>, we find that we cannot define the name
"signal_function_pointer". (It is reserved to the user. User gets
the non-"__" names, implementor gets the "__" names, and the two
never collide.) So we either write the hairy version, or typedef
a double-underscore name.
 
B

Ben C

... you can read this:

int (*fn)(int) = f;

as "fn is a pointer, and *fn is a function that takes an int and return
an int". ...
I'd appreciate a better explanation of function type syntax myself. I
think I've just got used to them rather than ever understood them.

The above is exactly the right description.

Dennis has said that the rule for C is "declaration mirrors use".
[...]

Brilliant explanation, thank you very much.
 
C

CBFalconer

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top