C/C++

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • advantage of using typedefs

    29 answers - 548 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    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
  • No.1 | | 614 bytes | |

    junky_fellow@yahoo.co.in a :
    I wanted to know what advantage do we get by typedefs ? Why we did not
    declare
    offset simply as
    long off_t;

    It's often a portability issue. Imagine you want a type that hold the
    biggest possible unsigned integer.

    You will have this in C90:

    typedef unsigned long biggest_int_t;

    and that on C99:

    typedef unsigned long long biggest_int_t;

    With the help of some smart macros and #ifxxx directives, After a simple
    recompile, the type will automagically be corrected after a simple
    recompile of the project/lib or whatever.
  • No.2 | | 993 bytes | |


    Emmanuel Delahaye wrote:
    junky_fellow@yahoo.co.in a :
    I wanted to know what advantage do we get by typedefs ? Why we did not
    declare
    offset simply as
    long off_t;

    It's often a portability issue. Imagine you want a type that hold the
    biggest possible unsigned integer.

    You will have this in C90:

    typedef unsigned long biggest_int_t;

    and that on C99:

    typedef unsigned long long biggest_int_t;

    With the help of some smart macros and #ifxxx directives, After a simple
    recompile, the type will automagically be corrected after a simple
    recompile of the project/lib or whatever.

    Thanx for your reply, Emmanuel. But if this is the case (ie we need
    the biggest possible
    unsigned integer to hold offset ) then why not declare
    unsigned long long offset;
    I believe unsigned long long should be highest possible integer type ?
    am I wrong ?

    Is there any other reason for doing that ?

  • No.3 | | 818 bytes | |

    28 Jan 2006 00:50:55 -0800, in comp.lang.c ,
    "junky_fellow@yahoo.co.in" <junky_fellow@yahoo.co.inwrote:

    (concerning typdef'ing)

    >Thanx for your reply, Emmanuel. But if this is the case (ie we need
    >the biggest possible unsigned integer to hold offset ) then why not declare
    >unsigned long long offset;


    Because then its size would vary from platform to platform, and on a
    c90 implementation it would be an error. Some implementations spell
    "long long" as "__int64", others don't support it at all etc etc.

    >I believe unsigned long long should be highest possible integer type ?

    am I wrong ?

    You're right, but the size of long long varies from platform to
    platform
    Mark McIntyre
  • No.4 | | 940 bytes | |

    junky_fellow@yahoo.co.in wrote:
    Emmanuel Delahaye wrote:
    >
    >>junky_fellow@yahoo.co.in a :
    >>

    I wanted to know what advantage do we get by typedefs ? Why we did not
    declare
    offset simply as
    long off_t;
    >>
    >>It's often a portability issue. Imagine you want a type that hold the
    >>biggest possible unsigned integer.


    That is one good reason. I often define types for another: I create my
    own conceptual data type, which I document where the typedef occurs.
    For example:

    typedef unsigned long ticks;/* elapsed time, unit = 16 us. */

    ticks pulseWidth; /* width of last pulse */
    ticks pulseInterval; /* time between last 2 pulses */
    void DelayTicks (ticks delay);

    Here using ticks carries with it the type of data and the scaling.
  • No.5 | | 1480 bytes | |

    "Thad Smith" <ThadSmith@acm.orgwrote in message
    news:43db9067$0$81213$892e0abb@
    junky_fellow@yahoo.co.in wrote:
    >>It's often a portability issue. Imagine you want a type that hold the
    >>biggest possible unsigned integer.

    >

    That is one good reason. I often define types for another: I create my
    own conceptual data type, which I document where the typedef occurs.
    For example:

    typedef unsigned long ticks; /* elapsed time, unit = 16 us. */

    ticks pulseWidth; /* width of last pulse */
    ticks pulseInterval; /* time between last 2 pulses */
    void DelayTicks (ticks delay);

    Here using ticks carries with it the type of data and the scaling.

    From a tools perspective, this can be quite powerful. I've picked up
    development on a project where the former developer used typedefs just as
    you've done above. of the advantages is that when I encounter one of his
    typedef'd items, I can do a right-click on it and one of the menu options is
    "show typedef" which, when selected, shows the typedef, in context. Thus, I
    can immediately tell what he meant the variable or argument to hold or
    represent. Very handy, and saves a pile of time. Even in the older system
    where I have to find them using grep, it still means that once I've found it,
    the comments on what it means are right there.
    - Bill

  • No.6 | | 1359 bytes | |

    Mark McIntyre <markmcintyre@spamcop.netwrites:
    28 Jan 2006 00:50:55 -0800, in comp.lang.c ,
    "junky_fellow@yahoo.co.in" <junky_fellow@yahoo.co.inwrote:

    (concerning typdef'ing)
    >
    >>Thanx for your reply, Emmanuel. But if this is the case (ie we need
    >>the biggest possible unsigned integer to hold offset ) then why not declare
    >>unsigned long long offset;

    >

    Because then its size would vary from platform to platform, and on a
    c90 implementation it would be an error. Some implementations spell
    "long long" as "__int64", others don't support it at all etc etc.
    >
    >>I believe unsigned long long should be highest possible integer type ?

    >am I wrong ?
    >

    You're right, but the size of long long varies from platform to
    platform

    Yes, but if you want the biggest unsigned integer type, you have to
    accept that its size is going to vary.

    If you want a type whose size *doesn't* vary, you want
    something like uint64_t (and if you need this in C90, see
    <>). (I think most C90 implementations
    these days provide 64-bit integer types under some name.)

    BTW, C99 defines uintmax_t for precisely this purpose.
  • No.7 | | 763 bytes | |

    Sat, 28 Jan 2006 19:32:56 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:

    >Mark McIntyre <markmcintyre@spamcop.netwrites:
    >28 Jan 2006 00:50:55 -0800, in comp.lang.c ,
    >"junky_fellow@yahoo.co.in" <junky_fellow@yahoo.co.inwrote:
    >>

    I believe unsigned long long should be highest possible integer type ?
    am I wrong ?
    >>

    >You're right, but the size of long long varies from platform to
    >platform
    >
    >Yes, but if you want the biggest unsigned integer type, you have to
    >accept that its size is going to vary.


    which was my point.

    Mark McIntyre
  • No.8 | | 2453 bytes | |

    Mark McIntyre <markmcintyre@spamcop.netwrites:
    Sat, 28 Jan 2006 19:32:56 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:
    >>Mark McIntyre <markmcintyre@spamcop.netwrites:

    28 Jan 2006 00:50:55 -0800, in comp.lang.c ,
    "junky_fellow@yahoo.co.in" <junky_fellow@yahoo.co.inwrote:

    I believe unsigned long long should be highest possible integer type ?
    am I wrong ?

    You're right, but the size of long long varies from platform to
    platform
    >>
    >>Yes, but if you want the biggest unsigned integer type, you have to
    >>accept that its size is going to vary.

    >

    which was my point.

    Then I'm confused. junky_fellow's question was:

    But if this is the case (ie we need the biggest possible unsigned
    integer to hold offset ) then why not declare unsigned long long
    offset

    and you replied:

    Because then its size would vary from platform to platform, and on
    a c90 implementation it would be an error.

    The second point is valid (except for the many C90 implementations
    that provide "long long" as an extension), but I don't see what you're
    getting at with the first point. If you want the biggest possible
    unsigned integer, its size *will* vary from platform to platform, but
    you presented the variation in size as a reason not to use "unsigned
    long long".

    (And C99 allows extended integer types, so unsigned long long isn't
    necessarily the longest unsigned integer type. unsigned long long
    could be 64 bits, and uintmax_t could be 128 bits.)

    Either you want unsigned long long (whose size will vary, and which
    may not exist in a C90 implementation), or you want the largest
    unsigned integer type (whose size will vary), or you want an unsigned
    type that's exactly 64 bits (which probably exists, but it's not
    guaranteed in either C90 or C99). For the second and third cases, a
    typedef is reasonable -- and C99's <stdint.hprovides uintmax_t and
    uint64_t, respectively. For the first case, if you specifically want
    unsigned long long for some reason, a typedef would be silly. Mark,
    without going back to the question of what point you were making
    upthread, is there anything in this paragraph you disagree with?
  • No.9 | | 676 bytes | |

    2006-01-28, junky_fellow@yahoo.co.in <junky_fellow@yahoo.co.inwrote:
    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;

    your system. my system it's long long.

    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

  • No.10 | | 1409 bytes | |

    2006-01-28, Keith Thompson <kst-u@mib.orgwrote:
    Mark McIntyre <markmcintyre@spamcop.netwrites:
    >Sat, 28 Jan 2006 19:32:56 GMT, in comp.lang.c , Keith Thompson
    ><kst-u@mib.orgwrote:

    Mark McIntyre <markmcintyre@spamcop.netwrites:
    28 Jan 2006 00:50:55 -0800, in comp.lang.c ,
    "junky_fellow@yahoo.co.in" <junky_fellow@yahoo.co.inwrote:

    I believe unsigned long long should be highest possible integer type ?
    am I wrong ?

    You're right, but the size of long long varies from platform to
    platform

    Yes, but if you want the biggest unsigned integer type, you have to
    accept that its size is going to vary.
    >>

    >which was my point.
    >

    Then I'm confused. junky_fellow's question was:

    But if this is the case (ie we need the biggest possible unsigned
    integer to hold offset ) then why not declare unsigned long long
    offset

    and you replied:

    Because then its size would vary from platform to platform, and on
    a c90 implementation it would be an error.

    Regardless, there's a factual problem. The "offset" (assuming it is
    posix off_t) is used in places where it must be negative, and thus
    should not be unsigned anything. the original post said long, not
    unsigned long.
  • No.11 | | 6741 bytes | |

    In article <1138434930.477944.161090@g43g2000cwa.googlegroups. com>
    junky_fellow@yahoo.co.in <junky_fellow@yahoo.co.inwrote:
    >I wanted to know what advantage do we get by typedefs?


    In many ways, none at all.

    In one somewhat important way, a fairly big one.

    The underlying problem / solution here is "abstraction".

    Fundamentally, abstraction is all about removing unnecessary
    detail, while retaining necessary detail. (Not all abstractions
    *succeed* at this task, mind.) This is really the heart of
    most (maybe even all) computer programming.

    The real world is ineluctably complex. Computer programs tend to
    deal with simplified models. Even so, the simplified models are
    often (maybe even usually) sufficiently complicated that programmers
    cannot debug them without breaking them down even further. This
    is why we use higher level languages -- it is at least one reason,
    and I think one can argue that it is really the only reason, that
    we do not write everything in machine code -- and also why we
    break large programs into functions and (in langauges like C)
    data structures.

    C has a number of mostly-concrete data types: char, short, int,
    and long (and in C99 long long) and their unsigned variants; float,
    double, and long double; and pointers. (C99 adds complex number
    types. C also has "void", but this is mostly a degenerate case,
    and "enum", but enum is just a special case of "integral".) These
    types are already somewhat abstracted from the underlying machine;
    for instance, many microprocessors do not have hardware support
    (or full support) for 64 or even 32 bit integral types, and many
    only offer floating-point as an option (with a coprocessor) and/or
    need software assistance. Still, these types are generally "close
    to the metal", as the phrase goes: most CPUs implement most of them
    mostly in hardware (although complex numbers rarely have direct
    hardware support).

    In addition to these (and derived types -- which actually include
    all the pointer types as well as arrays; note also that "pointer
    to function returning T" is a data type, even though it points to
    a function type), C has the "user-defined abstract data type",
    which is spelled "struct". Whenever you declare or define a new
    struct, you get a new type. This new type is not compatible with
    any existing type:

    struct one { int val; } a;
    struct two { int val; } b;

    a = b; /* ERRR, type mismatch */

    User-defined types give you everything you need to make new,
    compiler-checked abstractions. A subroutine or function is also
    an abstraction, but unless you make it use or return a user-defined
    data type, it is possible to apply it to data of an inappropriate
    type. Consider, for instance, a subroutine that checks a
    temperature, which you might use in the control system for a
    nuclear reactor:

    void check_temperature(double the_value) { }

    If you are only checking "any old double" (as in this case), it is
    possible to call this with a length or pressure measurement by
    accident:

    double x;

    x = measure_something(); /* actually returns a pressure */

    check_temperature(x);

    A C compiler is not required to complain, and it would be surprising
    to find one that does. Make separate "temperature" and "pressure"
    data types, however, and we get:

    void check_temperature(struct temperature the_value) { }

    struct pressure x;

    x = measure_something();

    check_temperature(x);

    Now the compiler *is* required to complain.

    The problem with C's "typedef" is that it does *not* actually define
    types. Instead, it just defines an alias for some existing type.
    The aliases can be mixed freely. Thus if we try to use:

    typedef double temperature;
    typedef double pressure;

    we lose many of the advantages of abstract data types.

    At the same time, however, typedefs *do* give us a level of
    indirection. Consider ANSI/IS C "size_t", for instance. The
    Standard tells us that size_t is an unsigned integral type that
    holds the size (in bytes, which C calls "char"s) of an object. In
    general, size_t is an alias for one of three types: unsigned int,
    unsigned long, or unsigned long long. (Technically it could be an
    alias for unsigned char or unsigned short, or even one of the weird
    "extra" types allowed in C99, but in practice this does not occur.)

    This "level of indirection" acts as a sort of "leaky" abstract
    type. It fails to provide compile-time type-checking; we can use
    the wrong types all over the place and never even notice. But *if*
    we manage to use it correctly, it does insulate us from any changes
    needed when porting code from one machine to another. If size_t
    should be "unsigned int" on one 64-bit machine, but "unsigned long"
    on another, it *can* be. We can -- if we are sufficiently careful
    -- avoid assuming that it is either one or the other.

    The two things typedef gives you, that struct does not, are:
    - you do not need to write out the word "struct" each time, and
    - you can make the type-name a synonym for a fundamental, built
    in type (like "long" or "unsigned char"), rather than a
    user-defined abstract type.

    In C89 (but not C99), that second point is significant, because
    there is no way in C89 to write constants of user-defined type.
    In C99 we can do things like this:

    struct pressure { double val; };
    #define PRESSURE_UNKNWN ((struct pressure){-1})

    struct pressure p = estimate_pressure();

    some_loop_construct {

    if (some_condition)
    p = PRESSURE_UNKNWN; /* make sure we measure it below */

    if (p == PRESSURE_UNKNWN)

    }

    ( course, in C89 you can always write macros to deal with
    this, e.g., #define SET_TUNKNWN(pp) ((pp)->val = -1), but
    this is hardly elegant.)

    Structure values are often implemented relatively inefficiently.
    If this is the case for any particular situation / compiler, we
    can use typedef to get a "checked system", and then recompile to
    get a (presumably faster) "unchecked" version:

    #ifdef SLEAZE
    typedef double pressure;
    #define MK_CNSTANT(t, val) ((t)(val))
    #else
    typedef struct pressure pressure;
    struct pressure { double val; };
    #define MK_CNSTANT(t, val) ((t){val})
    #endif

    pressure estimate_pressure();
    #define PRESSURE_UNKNWN MK_CNSTANT(pressure, -1)

    Now we simply need to "#define SLEAZE" to get the "unchecked"
    version. (The MK_CNSTANT trick above is again C99-dependent.)
  • No.12 | | 1167 bytes | |

    Sat, 28 Jan 2006 21:31:09 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:

    >
    >Then I'm confused. junky_fellow's question was:
    >

    But if this is the case (ie we need the biggest possible unsigned
    integer to hold offset ) then why not declare unsigned long long
    offset
    >
    >and you replied:
    >

    Because then its size would vary from platform to platform, and on
    a c90 implementation it would be an error.

    >but I don't see what you're
    >getting at with the first point. If you want the biggest possible
    >unsigned integer, its size *will* vary from platform to platform, but
    >you presented the variation in size as a reason not to use "unsigned
    >long long".


    My point was that it will vary, and is thus a nonportable construct in
    terms of say file access. If all you care about is one platform, then
    no problem.
    But this thread was about why one would use typedefs, and one reason
    is to keep such platform specific stuff in a single place.
    Mark McIntyre
  • No.13 | | 1961 bytes | |

    Mark McIntyre <markmcintyre@spamcop.netwrites:
    Sat, 28 Jan 2006 21:31:09 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:
    >>Then I'm confused. junky_fellow's question was:
    >>

    >But if this is the case (ie we need the biggest possible unsigned
    >integer to hold offset ) then why not declare unsigned long long
    >offset
    >>
    >>and you replied:
    >>

    >Because then its size would vary from platform to platform, and on
    >a c90 implementation it would be an error.
    >
    >>but I don't see what you're
    >>getting at with the first point. If you want the biggest possible
    >>unsigned integer, its size *will* vary from platform to platform, but
    >>you presented the variation in size as a reason not to use "unsigned
    >>long long".

    >

    My point was that it will vary, and is thus a nonportable construct in
    terms of say file access. If all you care about is one platform, then
    no problem.
    But this thread was about why one would use typedefs, and one reason
    is to keep such platform specific stuff in a single place.

    course it will vary. junky_fellow *specifically* asked about "the
    biggest possible unsigned integer". Maybe that's not the best thing
    to use for a file offset -- and if that was your point, you might have
    said so.

    But *if* you need the biggest possible unsigned integer, for whatever
    reason, it's perfectly sensible to use a typedef for it (or, in C99,
    to use the existing uintmax_t). There could be any number of reasons
    you'd want that. course, any code using it would have to allow for
    the fact that the size will vary from one platform to another.

    I notice that you snipped the direct question that I asked you.
  • No.14 | | 1788 bytes | |


    <junky_fellow@yahoo.co.inwrote in message
    news:1138434930.477944.161090@
    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

    In response to:
    I wanted to know what advantage do we get by typedefs ?

    I always seem to have problems with structures when they aren't typedef'd.
    When structures are typedef'd, you can cast values to structure elements and
    take the size of structure elements without actually having a valid,
    allocated, and filled data structure. For example, say you have three
    structures which should be nested but are separate. Now, you need some data
    from the third structure. But, you have a raw buffer that corresponds to
    the first structure, and, of course, contains the data for second and third
    structures. How do you get to the data in the third structure? Using
    typedef'd structures and casts, you can access the data from the third
    structure in the raw buffer without allocating space for or filling in the
    structures. You only need to allocate space for the raw buffer and
    variables which are assigned data from the third structure. You have total
    access to any data in the raw buffer, but you don't need to allocate and
    fill any intermediate structures.

    Rod Pemberton

  • No.15 | | 2031 bytes | |

    "Rod Pemberton" <dont_have@bitbucket.cmmwrites:
    <junky_fellow@yahoo.co.inwrote in message
    news:1138434930.477944.161090@
    []
    >I wanted to know what advantage do we get by typedefs ?

    []
    I always seem to have problems with structures when they aren't typedef'd.
    When structures are typedef'd, you can cast values to structure elements and
    take the size of structure elements without actually having a valid,
    allocated, and filled data structure. For example, say you have three
    structures which should be nested but are separate. Now, you need some data
    from the third structure. But, you have a raw buffer that corresponds to
    the first structure, and, of course, contains the data for second and third
    structures. How do you get to the data in the third structure? Using
    typedef'd structures and casts, you can access the data from the third
    structure in the raw buffer without allocating space for or filling in the
    structures. You only need to allocate space for the raw buffer and
    variables which are assigned data from the third structure. You have total
    access to any data in the raw buffer, but you don't need to allocate and
    fill any intermediate structures.

    Given:

    typedef struct foo_s {
    /* member declarations */
    } foo_t;

    I can't think of anything you can do with "foo_t" that you can't just
    as easily do with "struct foo_s" -- which is why I prefer the simpler:

    struct foo {
    /* member declarations */
    };

    Can you provide an example where the typedef gives you a real
    advantage? (Saving keystrokes doesn't count as a "real advantage".)

    I'm not sure I understand your example anyway; the use of casts always
    makes me nervous. If you have "three structures which should be
    nested but are separate", what's stopping you from nesting them?
    But in any case, a cast to "struct foo*" is as valid as a cast to
    "foo_t*".
  • No.16 | | 360 bytes | |

    Keith Thompson wrote:

    snip

    I notice that you snipped the direct question that I asked you.

    As a general principle I suggest that snipping should be done in
    units of paragraphs. This reduces the alteration of meaning by
    quoting out of context. This might also have the desirable side
    effect of encouraging reasonable paragraphing.
  • No.17 | | 754 bytes | |

    CBFalconer <cbfalconer@yahoo.comwrites:
    Keith Thompson wrote:
    >>

    snip
    >>

    >I notice that you snipped the direct question that I asked you.
    >

    As a general principle I suggest that snipping should be done in
    units of paragraphs. This reduces the alteration of meaning by
    quoting out of context. This might also have the desirable side
    effect of encouraging reasonable paragraphing.

    I think the snipping was done in units of paragraphs. The question
    was part of an entire paragraph that was snipped. (Not that he's
    under any obligation to answer any particular question, of course.)
  • No.18 | | 2149 bytes | |


    "Keith Thompson" <kst-u@mib.orgwrote in message
    news:lnirs2sh0v.fsf@nuthaus.mib.org
    "Rod Pemberton" <dont_have@bitbucket.cmmwrites:
    <junky_fellow@yahoo.co.inwrote in message
    news:1138434930.477944.161090@
    []
    >I wanted to know what advantage do we get by typedefs ?

    []
    I always seem to have problems with structures when they aren't
    typedef'd.
    When structures are typedef'd, you can cast values to structure elements
    and
    take the size of structure elements without actually having a valid,
    allocated, and filled data structure. For example, say you have three
    structures which should be nested but are separate. Now, you need some
    data
    from the third structure. But, you have a raw buffer that corresponds
    to
    the first structure, and, of course, contains the data for second and
    third
    structures. How do you get to the data in the third structure? Using
    typedef'd structures and casts, you can access the data from the third
    structure in the raw buffer without allocating space for or filling in
    the
    structures. You only need to allocate space for the raw buffer and
    variables which are assigned data from the third structure. You have
    total
    access to any data in the raw buffer, but you don't need to allocate and
    fill any intermediate structures.

    Given:

    typedef struct foo_s {
    /* member declarations */
    } foo_t;

    I can't think of anything you can do with "foo_t" that you can't just
    as easily do with "struct foo_s" -- which is why I prefer the simpler:

    struct foo {
    /* member declarations */
    };

    Can you provide an example where the typedef gives you a real
    advantage? (Saving keystrokes doesn't count as a "real advantage".)

    I'm not sure I understand your example anyway; the use of casts always
    makes me nervous. If you have "three structures which should be
    nested but are separate", what's stopping you from nesting them?
    But in any case, a cast to "struct foo*" is as valid as a cast to
    "foo_t*".
  • No.19 | | 4140 bytes | |

    "Rod Pemberton" <dont_have@bitbucket.cmmwrites:
    "Keith Thompson" <kst-u@mib.orgwrote in message
    news:lnirs2sh0v.fsf@nuthaus.mib.org
    >"Rod Pemberton" <dont_have@bitbucket.cmmwrites:
    ><junky_fellow@yahoo.co.inwrote in message
    >news:1138434930.477944.161090@
    >[]
    >>I wanted to know what advantage do we get by typedefs ?

    >[]
    >I always seem to have problems with structures when they aren't
    >typedef'd. When structures are typedef'd, you can cast values to
    >structure elements and take the size of structure elements
    >without actually having a valid, allocated, and filled data
    >structure. For example, say you have three structures which
    >should be nested but are separate. Now, you need some data from
    >the third structure. But, you have a raw buffer that corresponds
    >to the first structure, and, of course, contains the data for
    >second and third structures. How do you get to the data in the
    >third structure? Using typedef'd structures and casts, you can
    >access the data from the third structure in the raw buffer
    >without allocating space for or filling in the structures. You
    >only need to allocate space for the raw buffer and variables
    >which are assigned data from the third structure. You have total
    >access to any data in the raw buffer, but you don't need to
    >allocate and fill any intermediate structures.
    >>

    >Given:
    >>

    >typedef struct foo_s {
    >/* member declarations */
    >} foo_t;
    >>

    >I can't think of anything you can do with "foo_t" that you can't just
    >as easily do with "struct foo_s" -- which is why I prefer the simpler:
    >>

    >struct foo {
    >/* member declarations */
    >};
    >>

    >Can you provide an example where the typedef gives you a real
    >advantage? (Saving keystrokes doesn't count as a "real advantage".)


    (Please don't quote signatures.)

    [snip]

    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;
    --
    This is same as the following sequence of 'pseudo' code. We take the
    address of buf:
    '&buf'

    which is then cast as a 'partition boot sector':
    '(partition_boot_sector *)&buf'

    Now that we have a 'partition boot sector', we locate the 'bios parameter
    block':
    'partition_boot_sector->bpb'

    We then cast the address of the 'bios parameter block' as a 'bios parameter
    block':
    '(bios_parameter_block *)&(partition_boot_sector->bpb)'
    This address should be something like &buf+12 or buf[12].

    Now that we have a 'bios parameter block', we locate the number of heads:
    'bios_parameter_block->number_of_heads'
    This address of this data should be something lik &buf+12+16 or buf[28].
    [snip]
    Hope that helps.

    Um, not really.

    It's hard to tell without seeing the actual code, but I presume
    bios_parameter_block and partition_boot_sector are typedefs for some
    struct types. Let's assume they're called "struct bios_parameter_block"
    and "struct partition_boot_sector".

    Then your statement

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

    could as easily be written

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

    As I said, there's nothing you can do with typedefs for struct types
    that you can't do just as easily with the struct types themselves.
  • No.20 | | 3612 bytes | |

    >"Rod Pemberton" <dont_have@bitbucket.cmmwrites:
    When structures are typedef'd, you can cast values to
    structure elements and take the size of structure elements
    without actually having a valid, allocated, and filled data
    structure.

    (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.)

    >"Keith Thompson" <kst-u@mib.orgwrote in message
    >news:lnirs2sh0v.fsf@nuthaus.mib.org
    >Given:
    >>

    >typedef struct foo_s {
    >/* member declarations */
    >} foo_t;
    >>

    >I can't think of anything you can do with "foo_t" that you can't just
    >as easily do with "struct foo_s"


    In article <ksc0b3-bp52.ln1@news.infowest.com>
    Rod Pemberton <dont_have@bitbucket.cmmwrote:
    >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 :-)
  • No.21 | | 1980 bytes | |


    junky_fellow@yahoo.co.in wrote:
    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.

  • No.22 | | 454 bytes | |

    John Bode wrote:

    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
    S), regardless of the underlying hardware.

  • No.23 | | 858 bytes | |

    2006-01-30, tedu <tu@zeitbombe.orgwrote:
    John Bode wrote:
    >
    >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
    S), regardless of the underlying hardware.

    Says who?

    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.
  • No.24 | | 1151 bytes | |

    Jordan Abel wrote:
    2006-01-30, tedu <tu@zeitbombe.orgwrote:
    John Bode wrote:
    >
    >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
    S), regardless of the underlying hardware.

    Says who?

    Group Base Specifications Issue 6:

    off_t
    Used for file sizes.

    the P mentioned openbsd; that's one. as i said, it depends on the S,
    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 S.

    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.

  • No.25 | | 1563 bytes | |

    2006-01-30, tedu <tu@zeitbombe.orgwrote:
    Jordan Abel wrote:
    >2006-01-30, tedu <tu@zeitbombe.orgwrote:
    >John Bode wrote:
    >>
    >>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
    >S), regardless of the underlying hardware.
    >>

    >Says who?
    >>

    >Group Base Specifications Issue 6:
    >>

    >off_t
    >Used for file sizes.
    >

    the P mentioned openbsd; that's one. as i said, it depends on the S,
    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 S.

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

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

    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.
  • No.26 | | 472 bytes | |

    Sun, 29 Jan 2006 20:36:40 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:

    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
  • No.27 | | 450 bytes | |

    Mark McIntyre <markmcintyre@spamcop.netwrites:
    Sun, 29 Jan 2006 20:36:40 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:
    >
    >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.

    course there is. What do you think uintmax_t is for?
  • No.28 | | 693 bytes | |

    Mon, 30 Jan 2006 23:10:59 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:

    >Mark McIntyre <markmcintyre@spamcop.netwrites:
    >Sun, 29 Jan 2006 20:36:40 GMT, in comp.lang.c , Keith Thompson
    ><kst-u@mib.orgwrote:
    >>

    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.
    >

    course there is. What do you think uintmax_t is for?

    And whats its value? Please give a portable answer.
    Mark McIntyre
  • No.29 | | 881 bytes | |

    2006-02-01, Mark McIntyre <markmcintyre@spamcop.netwrote:
    Mon, 30 Jan 2006 23:10:59 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:
    >
    >>Mark McIntyre <markmcintyre@spamcop.netwrites:

    Sun, 29 Jan 2006 20:36:40 GMT, in comp.lang.c , Keith Thompson
    <kst-u@mib.orgwrote:

    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.
    >>

    >course there is. What do you think uintmax_t is for?
    >

    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.

    Mark McIntyre

Re: advantage of using typedefs


max 4000 letters.
Your nickname that display:
In order to stop the spam: 9 + 8 =
QUESTION ON "C/C++"

EMSDN.COM