[LCP]typedefs in .h

Greg Black gjb at gbch.net
Sat Jan 19 10:58:20 UTC 2002


Emil Tantilov wrote [reformatted -- please fix your mailer so
that it doesn't mutilate stuff you quote]:

| > But let me refine that answer Emil.
| > 
| > The method you were given will give you the "actual" type in
| > THIS (ie: some specific) implementation. You can also
| > examine the headers themslves (and remember, you can use an
| > option specifying that these "hidden" things be expanded in
| > the compile listing).  They aren't "buried", only seems that
| > way because the default is "don't expand and show me".
| > 
| > BUT --- there is no ACTUAL type for these things in C
| > itself. That is the whole purpose of having them as abstract
| > types defined via typedefs in headers. It makes your C
| > source code independent of the way these must be defined for
| > some specific implementation.  Since any actual compile is
| > for some specific implementation, as long as the the right
| > header libraries* are used for that implementation,
| > everything will work out WITHOUT any need to edit the source
| > code.
| > 
| > Proper coding technique is for your code to make no
| > assumptions about things that are not defined in C like "how
| > long is an integer"
| 
|  I agree and understand the purpose of things being
| made the way they are. However (I should've asked the
| question in a different way perhaps ...) if I try to
| display the result I *will* need to know the type,
| otherwise the result won't be accurate (let's say if I
| display number instead of text or char ...). In this
| case fstat(), I can't display st_dev, not to mention I
| have no idea what it represent and in what format ...

There are two parts to this.

First, as a budding Unix programmer, you just have to learn
about the types that are used and what sort of representation
they have.  With a few rare and specialised exceptions, they
will be consistent in basic type across implementations.  So a
pid_t will always be an integer, but its size may vary.  What
you have to do is learn about these basic types, and the man
pages and the system header files will tell you what you need to
know -- and you must be prepared to read these things.

Then you can write code that will work for the purpose you have
in mind.  In general, except for when you want to display data
(e.g., with printf()), you don't need to know about the sizes of
things.  In the old days, you didn't even need to know for
printf() because all integer types could be printed as a /long/,
all floating types could be printed as /double/, etc.  But now
we have extended types to make up for the stupid ways that
64-bit and 128-bit processors have been handled and things are
not quite so simple.

However, there is still a simple solution that will make this
kind of code easy to get right and that will teach you about
defensive programming in any case -- so it's worth study.

Take the following trivial program:

    #include <stdio.h>
    #include <unistd.h>

    int
    main(void)
    {
        pid_t pid = getpid();
        printf("pid = %ld\n", (long) pid);
        return 0;
    }

This will most probably work for a long time, perhaps for ever.
But you can't be sure that a /pid_t/ will be guaranteed to fit
in a /long/ and you certainly would not want to pay the cost of
casting it to a /long long/, so you can add two lines to the
program as shown below:

    #include <assert.h>
    #include <stdio.h>
    #include <unistd.h>

    int
    main(void)
    {
        pid_t pid = getpid();
        assert(sizeof(pid) <= sizeof(long));
        printf("pid = %ld\n", (long) pid);
        return 0;
    }

Now your program will work for as long as a /pid_t/ can be
stored in a /long/, but the program will abort with a useful
message if it's ever compiled on an architecture where the
assertion fails.  By then you would probably have forgotten
about the issue, but you are now assured that the oversight
won't come back to bite you.

Learn about assert() and use it.

Greg



More information about the linuxCprogramming mailing list