is it any good to use typedef ?

D

dreamcatcher

I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ? and I also know that when a data type
being typedefed become an abstract data type, so what exactly is an
abstract data type, is it any good ?
 
J

Joona I Palaste

dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ? and I also know that when a data type
being typedefed become an abstract data type, so what exactly is an
abstract data type, is it any good ?

Typedeffing structs is a bad idea, but there *are* good uses for
typedef. Particularly with function pointers.

Suppose you want a function that takes in an array of function
pointers (actually a pointer to function pointers) and returns one of
the function pointers it got. These functions each take multiple
parameters and return one value. (Suppose they are of the form int
function(int, int).)
How would you write the prototype for this kind of function? Without
typedef, it *is* possible, but I'm not even going to try it. Some C
expert will provide you one.
However, with typedef, it's easy:
typedef int (*func_ptr)(int, int);
func_ptr selectOneOfTheFunctions(func_ptr functions[]);

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"You could take his life and..."
- Mirja Tolsa
 
B

Bertrand Mollinier Toublet

Joona said:
Typedeffing structs is a bad idea,

I am afraid this subject is pretty holy-warish. At any rate, let me
disagree with you. There are occurences of good usage for a typedef'd
structure. Let's say you are creating an abstract data type, foo. You
can create an objet of type foo, destroy an objet of type foo and bar an
objet of type foo. For now you choose to implement foo as a struct, but
this is not required by your interface design. The one good way I know
of how to do that is to offer the following interface:

/*-------------------8<---foo.h------------------------------*/
#ifndef FOO_H
#define FOO_H

typedef struct foo_tag foo;

foo *foo_create(void);
void foo_bar(foo *f);
void foo_bar(foo *f);

#endif /* FOO_H */
/*-------------------8<---foo.h-----------------------------*/

/*-------------------8<---foo.c-----------------------------*/
#include <stdlib.h>
#include "foo.h"

struct foo_tag
{
int baz;
};

foo *foo_create(void)
{
foo *f;
f = malloc(sizeof *f);
if (NULL != f)
{
f.baz = 0;
}
return f;
}

void foo_bar(foo *f)
{
f.baz++;
}

void foo_destroy(foo *f)
{
free(f);
}
/*-------------------8<---foo.c-----------------------------*/

The day you refactor your code and find out that foo is much better
doing as an unsigned long than a structure, then all you have to do is
change the typedef line in your header and rewrite your implementation,
and, O gloria, allelluya, your interface hasn't changed !

I'd be interested to hear your arguments (if any) for why it is not a
good idea to typedef the struct in this case...
but there *are* good uses for
typedef.

Yes indeed ;-)
 
E

Eric Sosman

Joona said:
dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ? and I also know that when a data type
being typedefed become an abstract data type, so what exactly is an
abstract data type, is it any good ?

Typedeffing structs is a bad idea, but there *are* good uses for
typedef. Particularly with function pointers. [...]

Using or avoiding typedef with struct and union types
seems to be a matter of taste. I haven't seen any solid
technical reason to favor one practice over the other, so
it comes down to "de gustibus." (Personally, I'm in the
use-the-typedef camp -- but I have no particular quarrel
with people who feel otherwise.)

In addition to Joona's example of using typedef to
clarify gnarly function declarations, another place I find
typedef useful is in accommodating the uncertainties about
the sizes of C's types. For example, if I need an integer
type capable of representing values up to one million, it
is unsafe to use `int' because it might only go as high as
32767. `long' will go to at least 2147483647 and will
therefore suffice, but on some machines `long' will be
serious overkill and a waste of space. If I need to store a
large quantity of these numbers, I'd like to use the smallest
possible type.

Preprocessor tests coupled with typedef provide a way to
handle this portably and with minimal ugliness:

#include <limits.h>
#if CHAR_MIN <= -1000000 && 1000000 <= CHAR_MAX
typedef char Million;
#elif SHRT_MIN <= -1000000 && 1000000 <= SHRT_MAX
typedef short Million;
#elif INT_MIN <= -1000000 && 1000000 <= INT_MAX
typedef int Million;
#else
typedef long Million; /* known to suffice */
#endif

Thereafter, I can just write `Million' whenever I mean "a
sufficiently but not unnecessarily wide integer:"

Million *ptr = malloc(1234567 * sizeof *ptr);
Million smallest, largest;
Million func(void);

.... and so on; the result of all the grungy decision-making
has been conveniently packaged into the single word `Million'.

One shortcoming, though, is illustrated by this code:

Million value = 42;
printf ("value = %d\n", value); /* WRONG */

The problem is that if `Million' actually turns out to be an
alias for `long', the "%d" format specifier ought to be "%ld"
instead. One way to deal with this is to define a FMT_MILLION
macro as either "d" or "ld" in the testing above; you could
then write

printf ("value = %" FMT_MILLION "\n", value);

This works, but is clumsy to write and makes a mess for some
kinds of tools that assist with translating message strings
to multiple languages. I prefer the simpler

printf ("value = %ld\n", (long)value);

.... even though it may cost a little more at run time.

In short: typedef is convenient when you'd like to hide
the details of some type decisions from the eventual user
(possibly yourself).
 
J

John Bode

Joona I Palaste said:
Typedeffing structs is a bad idea,

Why? It's done in the standard library (see FILE). I've done it
quite a bit over the years. Why, exactly, is it a bad idea?
but there *are* good uses for
typedef. Particularly with function pointers.

Suppose you want a function that takes in an array of function
pointers (actually a pointer to function pointers) and returns one of
the function pointers it got. These functions each take multiple
parameters and return one value. (Suppose they are of the form int
function(int, int).)
How would you write the prototype for this kind of function?

Now you *know* this is a challenge that must be met...

f -- f
is an array -- f[]
of pointers -- *f[]
to functions -- (*f[])()
taking two int parameters -- (*f[])(int, int)
returning int -- int (*f[])(int, int)

g -- g
is a function -- g()
taking an array of pointers
to functions with two int
parameters returning int -- g(int (*f[])(int, int))
that returns a pointer to a
function -- (*(g(int (*f[])(int, int))))()
taking two int parameters -- (*(g(int (*f[])(int, int))))(int, int)
returning int -- int (*(g(int (*f[])(int, int))))(int,
int)

I think that's right.

Perfectly transparent.
Without
typedef, it *is* possible, but I'm not even going to try it. Some C
expert will provide you one.
However, with typedef, it's easy:
typedef int (*func_ptr)(int, int);
func_ptr selectOneOfTheFunctions(func_ptr functions[]);

Really, where's the fun in that?
 
M

Mark McIntyre

Why? It's done in the standard library (see FILE). I've done it
quite a bit over the years. Why, exactly, is it a bad idea?

typedefing pointers to structs is dangerous because the user may not
realise its a struct.
 
K

Kevin Easton

Mark McIntyre said:
typedefing pointers to structs is dangerous because the user may not
realise its a struct.

In the case of FILE it's appropriate, because you don't need to realise
it's a struct - you only ever manipulate pointers-to-FILE, and never
FILEs themselves. Any opaque data type you create yourself can be
similarly hidden behind a typedef without problems, but a transparent
data type probably shouldn't be.

In these matters I normally like to follow the example of the standard
library - an example of where a typedef should be used is the aformentioned
FILE, and an example of where a typedef shouldn't be used is struct tm.

- Kevin.
 
J

Jack Klein

Joona said:
dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ? and I also know that when a data type
being typedefed become an abstract data type, so what exactly is an
abstract data type, is it any good ?

Typedeffing structs is a bad idea, but there *are* good uses for
typedef. Particularly with function pointers. [...]

Using or avoiding typedef with struct and union types
seems to be a matter of taste. I haven't seen any solid
technical reason to favor one practice over the other, so
it comes down to "de gustibus." (Personally, I'm in the
use-the-typedef camp -- but I have no particular quarrel
with people who feel otherwise.)

In addition to Joona's example of using typedef to
clarify gnarly function declarations, another place I find
typedef useful is in accommodating the uncertainties about
the sizes of C's types. For example, if I need an integer
type capable of representing values up to one million, it
is unsafe to use `int' because it might only go as high as
32767. `long' will go to at least 2147483647 and will
therefore suffice, but on some machines `long' will be
serious overkill and a waste of space. If I need to store a
large quantity of these numbers, I'd like to use the smallest
possible type.

Preprocessor tests coupled with typedef provide a way to
handle this portably and with minimal ugliness:

#include <limits.h>
#if CHAR_MIN <= -1000000 && 1000000 <= CHAR_MAX
typedef char Million;
#elif SHRT_MIN <= -1000000 && 1000000 <= SHRT_MAX
typedef short Million;
#elif INT_MIN <= -1000000 && 1000000 <= INT_MAX
typedef int Million;
#else
typedef long Million; /* known to suffice */
#endif

Thereafter, I can just write `Million' whenever I mean "a
sufficiently but not unnecessarily wide integer:"

Million *ptr = malloc(1234567 * sizeof *ptr);
Million smallest, largest;
Million func(void);

... and so on; the result of all the grungy decision-making
has been conveniently packaged into the single word `Million'.

One shortcoming, though, is illustrated by this code:

Million value = 42;
printf ("value = %d\n", value); /* WRONG */

The problem is that if `Million' actually turns out to be an
alias for `long', the "%d" format specifier ought to be "%ld"
instead. One way to deal with this is to define a FMT_MILLION
macro as either "d" or "ld" in the testing above; you could
then write

printf ("value = %" FMT_MILLION "\n", value);

This works, but is clumsy to write and makes a mess for some
kinds of tools that assist with translating message strings
to multiple languages. I prefer the simpler

printf ("value = %ld\n", (long)value);

... even though it may cost a little more at run time.

In short: typedef is convenient when you'd like to hide
the details of some type decisions from the eventual user
(possibly yourself).

You realize, I hope, that the current C standard has done all of this
work for you?

You can include <inttypes.h> and use:

int_least32_t value;

....to define your type, and:

printf ("value = %" PRIdLEAST16 "\n", value);

....to print it, without creating your own type definitions and macros?

Note that it is quite possible and relatively easy to create your own
<stdint.h> and <inttypes.h> headers, at least up to 32 bit types, for
any conforming C89/90 compiler? If you do it properly all code that
uses them will still work just fine on an actual C99 compiler that
provides them.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jack Klein

typedefing pointers to structs is dangerous because the user may not
realise its a struct.

Here's the one place I agree with you. Our coding standards, which I
had a large part in creating, specifically forbid creating a typedef
for a pointer to any type of object, not just structures.

On the other hand, typedefs are required for all pointers to
functions.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
M

Mark McIntyre

In the case of FILE it's appropriate, because you don't need to realise
it's a struct - you only ever manipulate pointers-to-FILE, and never
FILEs themselves. Any opaque data type you create yourself can be
similarly hidden behind a typedef without problems, but a transparent
data type probably shouldn't be.

This is probably the key - if you never actually need to know the
structure of the struct, then hiding a pointer to it in a t ypedef is
safe enough.
 
R

Richard Heathfield

dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding,

Not just convenient, but also sensible IMHO for structs. Not pointers,
though - it's better not to hide them behind LPFOO nonsense.
but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ?

Sure, but you might want to wait until you've finished your course before
going that route.
and I also know that when a data type
being typedefed become an abstract data type,

Er, no, not really.
so what exactly is an
abstract data type, is it any good ?

"A set of data values, together with a set of operations on those values
that is defined without reference to the representation of the data values,
is called an abstract data type."
(Bruce J Maclennan, "Principles of Programming Languages".)

In C, opaque types form a relatively close approximation to this idea.
 
B

Ben Pfaff

dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ?

For what it's worth, a typedef is required for use of va_arg with
some types, e.g. pointer-to-function types.
 
J

John Bode

Mark McIntyre said:
typedefing pointers to structs is dangerous because the user may not
realise its a struct.

True, but there are times when I don't want the user to be able to
access or manipulate struct members directly. That's why when I do it
I present it as an ADT that cannot be directly manipulated, and
provide the functional interface necessary to use it.
 
D

Dan Pop

In said:
Why? It's done in the standard library (see FILE).

Where does the standard say that FILE is a struct?
I've done it
quite a bit over the years. Why, exactly, is it a bad idea?

When done for type saving purposes, it is a bad idea because it reduces
the code readability. It always helps to see a struct declaration
looking like a struct declaration.

When done for creating an abstract data type, like FILE, it is, of course
a good idea: it doesn't matter what's behind the typedef: it may be a
struct or it may be something else, the programmer should not care.

Dan
 
J

John Bode

Where does the standard say that FILE is a struct?

Forgive me. I committed the cardinal sin of assuming a particular
implementation. Of course FILE doesn't have to be implemented as a
struct.
When done for type saving purposes, it is a bad idea because it reduces
the code readability. It always helps to see a struct declaration
looking like a struct declaration.

When done for creating an abstract data type, like FILE, it is, of course
a good idea: it doesn't matter what's behind the typedef: it may be a
struct or it may be something else, the programmer should not care.

Ah. I was thinking exclusively in terms of ADTs. I almost never use
structs in any other capacity.
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top