Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

typedefs of data types ?

0 views
Skip to first unread message

Sriram

unread,
Dec 22, 2001, 2:19:59 AM12/22/01
to
Hi,
In typedefs, we commonly come across type definitions of data types
in header files.
Why data types are type defined. other than for better documentation
is there any other reason ?. I did not understand when ritchie says
they are for portability. what does ritchie mean by that.

Plz clarify,

Thanks,
Ram

Ioannis Vranos

unread,
Dec 22, 2001, 3:39:59 AM12/22/01
to
"Sriram" <vsri...@rediffmail.com> wrote in message
news:c087652b.01122...@posting.google.com...


We typedef system dependent types for portability. E.g. a system
specific integer type WD_LONG.


We do typedef WD_LONG splong;

splong x;

/* ...*/


When we want to migrate our code to another system we change the typedef
to that system's specific type or to another type.


E.g.

The line typedef WD_LONG splong;

becomes typedef WORD splong;


splong x;

/* ... */

where WORD is the equivallent system specific type of the new system.

Ioannis
--
* Ioannis Vranos
* Programming pages: http://www.noicys.f2s.com
* Alternative URL: http://run.to/noicys

pete

unread,
Dec 22, 2001, 7:44:11 AM12/22/01
to

size_t is unsigned on some systems, long unsigned on others.
There're a few others like that.

--
pete

Ioannis Vranos

unread,
Dec 22, 2001, 9:38:16 AM12/22/01
to
"pete" <pfi...@mindspring.com> wrote in message
news:3C2480...@mindspring.com...

long is never unsigned.

John

unread,
Dec 22, 2001, 10:04:48 AM12/22/01
to

"Ioannis Vranos" <noicys@no_spam.yahoo.com> wrote in message > >

> > size_t is unsigned on some systems, long unsigned on others.
> > There're a few others like that.
>
> long is never unsigned.

Are you sure about that. These are defined in a draft I have.

- minimum value for an object of type long int
LONG_MIN -2147483647

- maximum value for an object of type long int
LONG_MAX +2147483647

- maximum value for an object of type unsigned long int
ULONG_MAX 4294967295


John


Simon Biber

unread,
Dec 22, 2001, 10:00:39 AM12/22/01
to
"Ioannis Vranos" <noicys@no_spam.yahoo.com> wrote:

> "pete" <pfi...@mindspring.com> wrote:
> > size_t is unsigned on some systems, long unsigned on others.
> > There're a few others like that.
>
> long is never unsigned.

I think you misinterpreted Pete. He didn't say "long is unsigned", he said
size_t is "long unsigned". The two modifiers "long" and "unsigned" may be
specified in any order; "long unsigned var;" or "unsigned long var;" are
both correct.

Pete is correct to say that on some systems size_t is unsigned int, and on
some others, size_t is unsigned long int.

--
Simon.


willem veenhoven

unread,
Dec 22, 2001, 10:16:27 AM12/22/01
to
Ioannis Vranos wrote:

>
> pete wrote:
>
> > size_t is unsigned on some systems, long unsigned on others.
> > There're a few others like that.
>
> long is never unsigned.

Huh? I use a lot of unsigned longs, and I especially like them
for bitwise flags ... don't you?

Any girls around again, Ioannis?

willem

Thomas Pfaff

unread,
Dec 22, 2001, 11:25:14 AM12/22/01
to
"willem veenhoven" <wil...@veenhoven.com> wrote in message
news:3C24A3CB...@veenhoven.com...

He said "long is never unsigned" which is true. long and signed long are
the same. Why he said that is another thing, but I'm guessing he did not
know unsigned long is the same as long unsigned (which was news to me
too btw).


Morris Dovey

unread,
Dec 22, 2001, 11:14:02 AM12/22/01
to
Ioannis Vranos wrote:

> long is never unsigned.

Ioannis...

You might want to do a little research on that.

--
Morris Dovey
West Des Moines, Iowa USA

Barry Schwarz

unread,
Dec 22, 2001, 1:34:34 PM12/22/01
to

One of the benefits of a typedef can be significantly improved
readability. Consider three functions:

The first takes several int and float parameters and returns a
pointer to a 2d array of int, int(*)[5][10].

The second takes a different set of int and float parameters and
returns a pointer to a 2d array of int, int(*)[10][6].

The third takes a pointer to one of each of these functions and
returns a pointer to a 2d array of int, int(*)[5][6].

The declaration for each is

int (*f1(int, int, float, float, ..., int))[5][10]; /*not varadic,*/
int (*f2(int, float, float, ..., int))[10][6]; /*just lazy*/
int (*f3(int(*(*)(int,int,float,float,...,int))[5][10],
int(*(*)(int,float,float,...,int))[10][6]))[5][6];

With typedef:

typedef int (*f1_t(. . . ))[5][10];
typedef int (*f2_t(. . .))[10][6];

the declaration for the third function becomes
int (*f3(f1_t *, f2_t *))[5][6];

Its possibly even worse when a function returns a pointer to another
function. Let g be a function that takes three pointers to char and
returns a pointer to a function similar to strcmp. The declaration
would be

int(*g(char*,char*,char*))(const char*, const char*);

With typedef:

int strcmp_t(const char*, const char*);

the declaration becomes
strcmp_t * g(char*, char*, char*);


<<Remove the del for email>>

Chris Torek

unread,
Dec 22, 2001, 1:31:12 PM12/22/01
to
In article <c087652b.01122...@posting.google.com>

Sriram <vsri...@rediffmail.com> writes:
> In typedefs, we commonly come across type definitions of data types
>in header files.

(I think it would help to give some examples.)

>Why data types are type defined. other than for better documentation
>is there any other reason ?. I did not understand when ritchie says
>they are for portability. what does ritchie mean by that.

Presumably (as others noted) this refers to things like size_t and
ptrdiff_t (ANSI C types) and off_t (POSIX, not ANSI) and so on.

To really answer the question, though, we have to look at what
typedef *does*.

The obvious thing for typedef to do is just what its name says,
"define a new type", but unfortunately, that is exactly what it
fails to do. :-) Instead, it makes an alias -- a new name -- for
some old, existing type.

The typedef keyword acts, syntactically speaking, as if it were a
storage-class specifier, like "register", "auto", and "static"
(ignoring than the weird new C99 use for "static" in array sizes
in function parameters). Thus, since you might properly write:

register int i, j;
static double k, *l;
auto struct gronk *m, **n;

in various places, you can replace "register", "static", or "auto"
with "typedef", and write:

typedef union blergh o, *p, **q;

This changes what would ordinarily be three variable declarations
(for o, p, and q) into three type-alias declarations. The types
that are being aliased -- "union blergh" for o, "union blergh *"
for p, and "union o **" for q -- already exist; typedef just gives
you an extra, and often shorter, name for each of them.

So, now the question becomes:

Why would you define a new, sometimes shorter, name for an
old existing type?

and there are in fact many possible answers, including the really
obvious one, "the existing name is really long and I am too lazy
to write it out". :-)

A less-obvious one is that you might choose to use *different*
types, on different machines, to store the same "kind" (in some
fundamental sense) of information. The "size_t" type from the
various <stdwhatever.h> files is an example of this. C requires,
fundamentally, that all objects be made up of a set of "C bytes"
("unsigned char"s, really -- they may be larger than the machine's
"hardware bytes" if needed). This in turn implies that you can
measure the number of "C bytes" in any object, including compound
objects like arrays, using some nonnegative[%] integer. But what
integer type is large enough to hold such a size? On the PDP-11,
"unsigned int" will suffice, but on the DEC/Compaq Alpha, you need
"unsigned long".

[% One can even say "positive" because zero-byte objects are
prohibited, although I think that was a mistake.]

Thus, though the underlying type (unsigned int, or unsigned long)
may differ, the alias "size_t" will always get you a type that is
big enough to hold all possible "sizeof" values. This does, however,
expose a flaw in the plan: if size_t is some unknown, machine-dependent
type, how will you print such a value with printf()? The right
format is "%u" on the PDP-11 but "%lu" on the Alpha.

There are techniques for getting around this as well (see the C99
standard for some of the more complicated ones), but it shows some
of the problems with information-hiding -- which, indeed, is what
this is: hiding the implementation details and exposing only the
typedef, and any other things you decide you need to expose about
it in order for programmers to use it properly. Information-hiding
is in turn a part of abstraction, which is in a way what programming
is all about.

When it comes to hiding information and doing abstraction, however,
typedefs in C have what I consider a fundamental flaw. Remember that
typedef never defines a new type, just a new name for an existing
type. Quite often, this will wind up being a "struct", because you
will want to hold on to a number of values of various types, all in
one group. Modern languages that provide this sort of abstraction
usually throw "functions that operate on such objects" into the mix
as well, and call this something like a "class"; and indeed, the
closest thing C has to a C++ class is the struct, so this sort of
abstraction virtually always involves defining some set of structs.

The obvious question is: "so what?" Well, remember that structs
often *require* tags -- any time you are going to use forward
references, such as linked lists, you need a tag -- so you might as
well just always use tags. That means you will always be writing:

struct s {
struct s *next;
... more contents here ...
};

If you want to typedef these, you can do this:

typedef struct s somealias; /* refer to the incomplete type */
struct sometag {
somealias *next; /* can do this because we put typedef first */
... more contents here ...
};

but now it is clear that the alias is just an alias for "struct s",
and you could just expand it in place every time:

struct s {
struct s *next;
... more contents here ...
};

You can (and I say "should") use the same name for the tag as for
the alias, which saves mental effort and tends to improve, or at
least not harm, readability; so that means the alias merely saves
you from typing the word "struct".

Because of this, I find typedefs for structures almost (though not
quite entirely) useless. Just write "struct blah *p" instead of
"blah *p". You can even make a structure that contains only a
single ordinary type like "int" or "double" or whatever -- and
doing so induces automatic compiler type-checking that "typedef"
would not -- so "struct" can be considered *the* type abstraction
mechanism in C.

The nice thing about using the struct keyword is that it avoids
"namespace pollution". A name after a struct keyword is always a
structure tag, and is thus always in the "tag namespace". This is
quite different from typedef identifiers, which are in the "ordinary
identifier" namespace. This makes for potential name clashes,
which is what leads some programmers to use special conventions
for typedef names, such as the "_t" suffixes for POSIX:

pthread_t
pthread_key_t
pthread_attr_t
pthread_cond_t
pthread_mutex_t

and so on. (POSIX lays claim on "*_t", more or less, so any ANSI-C
programmer who intends to use POSIX as a supplemental standard
might be wise to leave this suffix to POSIX, and come up with yet
another convention.) I think the easiest answer is to avoid the
problem entirely, by writing out the word "struct". In effect,
the word "struct" means "the user-defined abstract type whose name
is...". Hence, I say that the keyword "struct" is really just a
funny acronym: STRange spelling for User-defined abstraCt Type.

In short, my answer to "what are typedefs for" is "very little:
use them as sparingly as possible; use struct for abstraction
instead, as much as possible."
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
El Cerrito, CA, USA Domain: to...@bsdi.com +1 510 234 3167
http://claw.eng.bsdi.com/torek/ (not always up) I report spam to abuse@.
"nos...@elf.eng.bsdi.com" *is* my address (one of many actually).

Ioannis Vranos

unread,
Dec 22, 2001, 4:19:34 PM12/22/01
to
"Ioannis Vranos" <noicys@no_spam.yahoo.com> wrote in message
news:10090319...@athprx02.forthnet.gr...
>
> long is never unsigned.

I saw a lot of anger around here ( :) ) so what i said is that the type
long is always signed, that is

long is always equivallent with signed long. The original poster however
meant that size_t sometimes is unsigned (=unsigned int), and sometimes
unsigned long. He is right on that, but a size_t can be a whatever
unsigned integer type (e.g. unsigned short).

pete

unread,
Dec 22, 2001, 6:31:16 PM12/22/01
to
Simon Biber wrote:

> The two modifiers "long" and "unsigned" may be
> specified in any order; "long unsigned var;" or "unsigned long var;"

Calling them "long unsigned" helps me remember %lu instead of %ul

--
pete

Richard Heathfield

unread,
Dec 23, 2001, 3:29:48 AM12/23/01
to
Ioannis Vranos wrote:
>
> "Ioannis Vranos" <noicys@no_spam.yahoo.com> wrote in message
> news:10090319...@athprx02.forthnet.gr...
> >
> > long is never unsigned.
>
> I saw a lot of anger around here ( :) )

No, you saw no anger. All you saw was the usual exasperation. This time,
for once, I don't think it was your fault.

> so what i said is that the type
> long is always signed, that is

Yes, you're right:

long num = 0; /* num is signed */

But, of course, this is also valid, as you know:

unsigned long othernum = 0;

>
> long is always equivallent with signed long. The original poster however
> meant that size_t sometimes is unsigned (=unsigned int), and sometimes
> unsigned long. He is right on that, but a size_t can be a whatever
> unsigned integer type (e.g. unsigned short).

Correct.

--
Richard Heathfield : bin...@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

John

unread,
Dec 23, 2001, 4:00:24 AM12/23/01
to

"Ioannis Vranos" <noicys@no_spam.yahoo.com> wrote in message
news:10090559...@athprx02.forthnet.gr...

> >
> > long is never unsigned.
>
> I saw a lot of anger around here ( :) ) so what i said is that the type
> long is always signed, that is
>
> long is always equivallent with signed long.

Anger is a strong word - I don't think that's what you saw.

>long is never unsigned.

I take 'long' to be the type that can have qualifiers, unsigned or signed.
Your intention is clear now though, long without a qualifier is never
unsigned.

Apologies if offence was perceived.

John

Lawrence Kirby

unread,
Dec 22, 2001, 7:45:04 AM12/22/01
to
In article <c087652b.01122...@posting.google.com>
vsri...@rediffmail.com "Sriram" writes:

>Hi,
> In typedefs, we commonly come across type definitions of data types
>in header files.

>Why data types are type defined. other than for better documentation
>is there any other reason ?.

If you mean types like size_t in system headers then this allows each
implementation to select the type that it most appropriate for it.

In user defined headers that is also true and it keep the type definition
in one place which makes it much easier to change should that be necessary.

>I did not understand when ritchie says
>they are for portability. what does ritchie mean by that.

For system headers it hides implementation details from the program code
which means that the program code is not dependent on implementation
details (or at least less so) which makes it more portable.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

Chris Torek

unread,
Dec 29, 2001, 5:56:17 PM12/29/01
to
In article <a02jhg$ofl$1...@elf.eng.bsdi.com> I wrote:
> typedef union blergh o, *p, **q;
>This changes what would ordinarily be three variable declarations
>(for o, p, and q) into three type-alias declarations. The types
>that are being aliased -- "union blergh" for o, "union blergh *"
>for p, and "union o **" for q -- already exist; typedef just gives
>you an extra, and often shorter, name for each of them.

That last one should read:

"union blergh **" for q

of course.

0 new messages