advantage of using typedefs

C

Chris Torek

(This is not quite right as stated, but I think I know what you
mean. However, there is nothing about "typedef" that makes any
difference here.)

It could be used anywhere nested structures are used, such as a database.
But, let's work with two hard disk structures: 'partition boot sector' and
'bios parameter block' (which is part of the 'partition boot sector'). Say
you have a buffer, 'buf[512]', of unsigned char for reading sectors off the
hard disk. Now, you've read the partition boot sector off the hard disk
into your buffer. How do you get access data in the 'bios parameter block'
by name instead of by 'buf[x]'? You cast the buffer to a 'partition boot
sector'. From the 'partition boot sector', you get the offset of the 'bios
parameter block' which is then cast to a 'bios parameter block'. From the
casted 'bios parameter block', you get the data you need. For example, to
get the number of heads (FAT32X) (this is from working code) :

unsigned char buf[512];
//some disk read routine which gets the partition boot sector, not the
master boot sector
num_heads=((bios_parameter_block *)&(((partition_boot_sector
*)&buf)->bpb))->number_of_heads;

Given:

struct bios_parameter_block { ... };
struct partition_boot_sector { ... };

(and no typedefs) I can rewrite what you have written as:

num_heads =
((struct bios_parameter_block *)
&(((struct partition_boot_sector *)&buf)->bpb))->number_of_heads;

though I would not write it like this, for a number of reasons.

Note that "&buf" is not needed here, because "buf" has type "array
512 of unsigned char", so that the "value" of buf falls under The
Rule and becomes a pointer to the first element of "buf". The
difference between &buf[0] and &buf is the type of the resulting
pointer.

If alignment and byte order are not concerns (i.e., if this code
is not intended to be portable), I would probably write:

struct partition_boot_sector *pbs;
struct bios_parameter_block *bpb;
...
pbs = (struct partition_boot_sector *)buf;
bpb = &pbs->bpb; /* (presumably this already has the right type) */
num_heads = bpb->number_of_heads;

If pbs->bpb does not have the correct type for some reason, the
second assignment would also need a cast.
As long as the layout of the structures are correct (i.e., packed, if
necessary) ...

Structure packing is of course not portable, so we should not even
mention it on comp.lang.c :)
 
J

John Bode

I was looking at the source code of linux or open BSD. What I found
that lots of typedefs
were used. For example, consider the offset in a file. It was declared
as
off_t offset;
and off_t is typedefed as
typedef long off_t;

I wanted to know what advantage do we get by typedefs ? Why we did not
declare
offset simply as
long off_t;

Similar is the case with size of file and so on.....

Does any one has any clue of why do we use typedefs in such cases ?

Thanx for any help advance ....

There are several reasons for doing this.

1. At some point in the future, a "long" may no longer be adequate for
representing offset values, and all offsets will need to be long long
(or some other type). By creating the typedef, you only need to make
that change in one place; i.e., change

typedef long off_t;

to

typedef long long off_t;

This is preferable to searching the source code for all offset
variables (which may or may not be named "offset") and changing their
definitions individually.

2. It allows you to implement the same types differently across
different platforms, depending on what's the most efficient or
practical for that platform. A 32-bit offset type would be wasteful on
a 16-bit platform, whereas it wouldn't be sufficient for a 64-bit
platform. Then you can have segmented architectures, were the offset
can be defined as a page number as well as displacement. Again, you
only have to make the change in one place, as opposed to finding and
changing every offset variable.

3. Sort of as a corollary to 2, it allows you to hide certain
implementation details from other programmers. You probably don't want
people making assumptions about the size of the offset available to
them, precisely because that value can change from platform to
platform.
 
T

tedu

John said:
3. Sort of as a corollary to 2, it allows you to hide certain
implementation details from other programmers. You probably don't want
people making assumptions about the size of the offset available to
them, precisely because that value can change from platform to
platform.

or the opposite, since off_t is intended to be 64-bit (depending on
OS), regardless of the underlying hardware.
 
J

Jordan Abel

or the opposite, since off_t is intended to be 64-bit (depending on
OS), regardless of the underlying hardware.

Says who?

Open Group Base Specifications Issue 6:

off_t
Used for file sizes.

All of the types shall be defined as arithmetic types of an appropriate
length, with the following exceptions: [Not off_t]

Additionally:
* blkcnt_t and off_t shall be signed integer types.
 
T

tedu

Jordan said:
Says who?

Open Group Base Specifications Issue 6:

off_t
Used for file sizes.

the OP mentioned openbsd; that's one. as i said, it depends on the OS,
but some people think it's more consistent to be able to address
"large" files even on 32 bit platforms than to always have off_t be a
native machine type, so that programs behave more or less consistently
on that OS.

the point was that sometimes typedef is used to make a type have a
fixed size, in contrast to a typedef like size_t that deliberately
varies in size.
 
J

Jordan Abel

the OP mentioned openbsd; that's one. as i said, it depends on the OS,
but some people think it's more consistent to be able to address
"large" files even on 32 bit platforms than to always have off_t be a
native machine type, so that programs behave more or less consistently
on that OS.

Yeah but who says it can't be 128 bits? Or 96 bits?

[besides, i believe linux/x86, for one, supports two different APIs, and the
default one is 32 bits]
 
M

Mark McIntyre

Of course it will vary. junky_fellow *specifically* asked about "the
biggest possible unsigned integer".

Ain't no such thing. I guess /that/ was my point.
I notice that you snipped the direct question that I asked you.

Did I? I didn't even notice it I'm afraid.
Mark McIntyre
 
J

Jordan Abel

And whats its value? Please give a portable answer.

Its value is the biggest possible unsigned integer type. Its biggest
possible value is UINTMAX_MAX.
 
K

Keith Thompson

Mark McIntyre said:
And whats its value? Please give a portable answer.

What do you mean "whats its value"? It's a type. What's the value of
int?

If you're asking about the maximum value of the type, you know as well
as I do that there is no portable answer. I never claimed that there
was *or that there should be*.

If you mean "value" in a more colloquial sense, uintmax_t can be
*very* valuable if it happens to be what you need.

You've been arguing (I think) that it's inappropriate to use a typedef
for something whose size can vary from one platform to another. Do
you believe that uintmax_t should not have been included in the C
standard? What about size_t? Or should size_t have been required to
have the same size across all implementations?

I would appreciate a direct answer to at least one of these questions.
 

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,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top