Thread: Why so many typedefs for the same thing?

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    269

    Why so many typedefs for the same thing?

    In this project I'm working on, they do this crap with just about every single struct:

    Code:
    typedef struct _format_list {
          ....
          ....
          ....
    }FormatRec, *FormatList, FormatStrDescRec, *FormatStrDescRec;

    What is the purpose of doing this????? There are literally hundreds of structs, and it makes it EXTREMELY hard to find what the heck is going in.

    Also, is *FormatList just a pointer? So instead of doing FormatRec * rec, one could just do FormatList rec???

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Yeah, that is the purpose of FormatList. Hate it also. Microsoft loves it for example. Depends if you have a good taste or not...

    Typedef the same thing...hmmm...strange indeed

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    269
    Quote Originally Posted by C_ntua View Post
    Yeah, that is the purpose of FormatList. Hate it also. Microsoft loves it for example. Depends if you have a good taste or not...

    Typedef the same thing...hmmm...strange indeed
    So there really is no functional purpose of having 4 different names for the SAME EXACT thing?

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Do me a favor.

    Break up that struct like so
    Code:
    typedef struct _format_list {
          ....
          ....
          ....
    }FormatRec;
    
    FormatRec *FormatList, FormatStrDescRec, *FormatStrDescRec;
    And see if it still compiles.

    If compiling still works (meaning there is nothing wrong with these lines) then everything, except FormatRec, is a variable, with FormatRec being a type. If compiling fails, then that means entire list is types.

    I don't think the entire list is types because I've only ever seen typedef used with one other word (as the new identifier), so that is how I think this is working, but you will have to experiment and see.

    And shoot whoever wrote this probably.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    269
    Quote Originally Posted by whiteflags View Post
    Do me a favor.

    Break up that struct like so
    Code:
    typedef struct _format_list {
          ....
          ....
          ....
    }FormatRec;
    
    FormatRec *FormatList, FormatStrDescRec, *FormatStrDescRec;
    And see if it still compiles.

    If compiling still works (meaning there is nothing wrong with these lines) then everything, except FormatRec, is a variable, with FormatRec being a type. If compiling fails, then that means entire list is types.

    I don't think the entire list is types because I've only ever seen typedef used with one other word (as the new identifier), so that is how I think this is working, but you will have to experiment and see.

    And shoot whoever wrote this probably.
    They are types. I left the struct in it's original form and did
    FormatRec rec;
    FormatList list;

    and it compiles. Hence, there are 4 names for the same ####ing type.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    269
    Is there any reason why this is done? Coding practice or what..?

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Your guess is as good as ours. Normally I think people typedef pointers so they don't get confused. You still need to count stars to dereference, so it isn't like a pointer typedef gets rid of the star syntax completely. If that makes more sense to people though, they will do it.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's some sort of ridiculous style that some people seem to love. Usually, it's just confusing. It's easy to get confused when working with several of those typedefs with pointers.
    You should do yourself a favor and use the real names and not the typedefs. You may shoot the ones who created them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by dayalsoap View Post
    Is there any reason why this is done? Coding practice or what..?
    Tough lesson to learn... There's usually more than one way of doing things and our way is not always the right way or even the only right way.

    The odds are very good that within the context of the project that made sense. Perhaps there were two different programmers --or groups of programmers-- and they had chosen slightly different names for the same thing. Now consider there are thousands of references to it in their code... Would it not be a lot more expeditious to hack up the typedef than changing throusands of lines of code?

    This doesn't mean it's good or even correct... but it is what it is and we get stuck with it.

    If you look at windows headers you will see that almost everything is "variations on a theme" they don't have just one handle ... they have HWND, HKEY, HCURSOR, HMENU and on... if you start tracking them back they all amount to the same thing... pointers to VOID. This is done because syntatically it makes some sense... You see HANDLE, you really don't know what you're looking at but HMENU tells the story... It's the same type but the name is very helpful in context.

    Similarly when defining structs I always trypedef the struct itself, an instance name and a pointer at the same time. Even if I don't use the pointer, I may in future revisions and it's syntatically helpful to have a predefined pointer name... For example:

    Code:
    // server info for registry
    typedef struct tSERVERINFO
      { USHORT        Port;                     // server port
        BYTE          Pings;                    // contact retries
        BYTE          Timeout;                  // retry spacing
        TCHAR         Password[MAX_PASSWORD]; } // server password      
      SERVERINFO, *pSERVERINFO;
    Note the notations used... tSERVERINFO is the typedef. SERVERINFO is the instance name. pSERVERINFO is a pointer to a tSERVERINFO struct. In my code the prepended "p" tells me right away I'm looking at a pointer the rest tells me it's a SERVERINFO struct, so I know the contents at the pointer ... Makes life a whole lot easier, at least for me.

    In the end it all boils down to styles and choices... none is particularly any better or worse as long as you remember that you might have to come back in 5 years and still be able to read your code.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CommonTater View Post
    If you look at windows headers you will see that almost everything is "variations on a theme" they don't have just one handle ... they have HWND, HKEY, HCURSOR, HMENU and on... if you start tracking them back they all amount to the same thing... pointers to VOID. This is done because syntatically it makes some sense... You see HANDLE, you really don't know what you're looking at but HMENU tells the story... It's the same type but the name is very helpful in context.
    This is different. This is called abstraction.
    Technically they all boil down to the same type, yet clearly they are different types. If I was writing C++, I would use the type system to make sure that even though they are the same type, they couldn't be assigned to each other or used interchangeably.
    In this case, it's usually a pointer to some internal Windows struct which we don't know anything about. Nor do we need to know; and in doing so, we protect our code from changes if those structs should change.
    So it would make sense to name these structs something rather than take a pointer to void. So this is a perfectly well use of typedefs. Abstraction is good.
    It's one of the few places where you can actually use abstraction in C. As usual, C is as lacking in this area as it is in all other areas.

    Note the notations used... tSERVERINFO is the typedef. SERVERINFO is the instance name. pSERVERINFO is a pointer to a tSERVERINFO struct. In my code the prepended "p" tells me right away I'm looking at a pointer the rest tells me it's a SERVERINFO struct, so I know the contents at the pointer ... Makes life a whole lot easier, at least for me.
    You are aware that you are not creating any instances, yes?
    tSERVERINFO is the name of the struct.
    SERVERINFO is a typedef for struct tSERVERINFO and pSERVERINFO is a typedef for struct iSERVERINFO*. Clearly, the later is obfuscation. The former is good since it lets us drop the "struct" (why C still requires this is a mystery to me).

    Of course, even though it is obfuscation, it is not necessarily better or worse than any other style.
    Last edited by Elysia; 09-20-2010 at 10:12 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Elysia View Post
    This is different. This is called abstraction.
    Technically they all boil down to the same type, yet clearly they are different types. If I was writing C++, I would use the type system to make sure that even though they are the same type, they couldn't be assigned to each other or used interchangeably.
    I've actually tested this... I can use the HANDLE type in place of almost any other handle type. This may not be universally true... but they do all rise from that one basic type.

    This is from winnt.h...
    Code:
    #ifdef STRICT
    typedef void *HANDLE;
    #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
    #else
    typedef PVOID HANDLE;
    #define DECLARE_HANDLE(name) typedef HANDLE name
    #endif
    typedef HANDLE *PHANDLE;
    In this case, it's usually a pointer to some internal Windows struct which we don't know anything about. Nor do we need to know; and in doing so, we protect our code from changes if those structs should change.
    Agreed.


    So it would make sense to name these structs something rather than take a pointer to void. So this is a perfectly well use of typedefs. Abstraction is good.
    It's one of the few places where you can actually use abstraction in C. As usual, C is as lacking in this area as it is in all other areas.
    Oh, I dunno... I've worked in Pascal, C, C++ and Delphi... I still keep coming back to C.


    You are aware that you are not creating any instances, yes?
    Perfectly. That's why I called it an instance name... as in...

    SERVERINFO ThisServer;

    Of course, even though it is obfuscation, it is not necessarily better or worse than any other style.
    Exactly... in the windows context it makes sense. It should be understood that the language does support it, in the interests of knowing the whole language... but style is not a language feature in C... so "your mileage may vary"... LOL.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CommonTater View Post
    I've actually tested this... I can use the HANDLE type in place of almost any other handle type. This may not be universally true... but they do all rise from that one basic type.
    Yes. They really shouldn't be the same thing. Or that is, you shouldn't be able to use them interchangeably like you are, but that is another pitfall of C. There is simply no way of separating them into different types without having to retort to define hacks.
    But even they aren't perfect; they cannot act and feel like natural integral types. They would always be some sort of a struct. This is fine for abstraction, though.

    Oh, I dunno... I've worked in Pascal, C, C++ and Delphi... I still keep coming back to C.
    Oh, I dunno... I've worked with VB, C++, C# (not so much, though), Java (thankfully not C, though; I deal with it enough on the forum all days long )... yet I keep coming back to C++.
    Anyway, there are always people who are going to love some aspect of a language. Can't be helped.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Elysia View Post
    Oh, I dunno... I've worked with VB, C++, C# (not so much, though), Java (thankfully not C, though; I deal with it enough on the forum all days long )... yet I keep coming back to C++.
    Anyway, there are always people who are going to love some aspect of a language. Can't be helped.
    The thing with me is I just hated object oriented programming... I don't know why but it just doesn't make any sense to me. I've always been most comfortable and most productive in procedural pascal or C... since pascal is pretty much dead, I'm left with C.

    Also, I'm not a full time programmer and don't want to be one. I write the occasional small program as a problem solver for my few remaining customers (hardware support) but mostly I mess with code for the challenge and the satisfaction of creating something new. My main skills are in Audio and Electronics, not programming.

    I suppose you could say: "I C for a hobby"
    Before electronic parts were reduced to the size of fly poop it was: "IC for a hobby"


  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'm just a hobbyist C++ coder. But I find there's just so much to mess with. There's not just OOP--there is generic programming, as well. That's a challenge usually. To be able to create something generic that can be used almost everywhere without having to change any code.
    You should try it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Quote Originally Posted by Elysia View Post
    I'm just a hobbyist C++ coder. But I find there's just so much to mess with. There's not just OOP--there is generic programming, as well. That's a challenge usually. To be able to create something generic that can be used almost everywhere without having to change any code.
    You should try it.
    Sorry to but in, but I have to agree.

    I'm a young hobbyist programmer myself and I've worked with Python, PHP, MySQL, Java, Javascript, HTML, etc...but mostly Assembly, C and C++. Maybe it is because I started out with C++ instead of C, but I find C++ useful in all kinds of ways.

    Generic Programming, for one, is something that I always try to endorse. Much like you described it, I want to know that my code will work anywhere.

    But what I like about C++ is the ability to create severe abstraction layers. For starters, there's Classes. Sure, you can just have a structure in C and have a virtual function table, etc etc, but that wouldn't be "C as in C" code; there are limitations to this method. Classes allow me to clearly name things and establish real connections between them. They allow a programmer to create something that models an abstract idea in the brain or in the real world. In this way, we can associate the concept of Object to Body Part, to Head, which in turn contains other body parts such as eyes, mouth, etc. I find that this is extremely useful for rapid development of software -- not the most efficient, though.

    For instance, in a card game, my natural instinct is/was to create a Card class, then a Hand class (group of cards), from which I can derive a Deck (group of cards with special characteristics), etc... And yet, methods will do OK with either Deck or Hand -- it's so much simpler than "pure C". If I have to add another graphical layer, most of the code can remain the same if I just derive from Hand and create GfxHand (or something similar), etc...

    Another example was a polynomial calculator I built. First there's terms=monomials, then there's polynomials, which are sets of terms. All operations and methods (Newton's, etc...) could be clearly expressed and mapped one-to-one with the algorithms that we use in a day-to-day basis. Sure, it's not --efficient--, but it is good enough to allow a programmer to see the code and almost instantly understand it.

    Then there's operator overloading. I'm not too fond of some of it, but it really allows for someone to create a unique dialect of C++, if I may. Overloading almost anything allows for just that -- anything.

    Then implicit (is that what it's called?) construction and destruction allows for extremely useful things such as auto-pointers and RAII, which get a whole lot out of your shoulders. This is why I really prefer C++ over C, even though I'm not the type of coder that banishes mixing them or enforces only std::cout of prntf and vectors over arrays (I have some projects lying around that do just that).

    Of course, C++ has its disadvantages. It does more things behind your back, which gives you advantages and disadvantages of its own. I don't think that it's the ideal language for an OS -- at least not for the very first layers. For that, I prefer to stick with C and Assembly.

    Just my two cents.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. most challenging thing to program
    By volk in forum A Brief History of Cprogramming.com
    Replies: 52
    Last Post: 03-28-2003, 03:56 PM
  2. newbie needs help comprehending simple thing
    By A helpless one in forum C++ Programming
    Replies: 6
    Last Post: 12-16-2002, 09:23 PM
  3. Replies: 22
    Last Post: 11-08-2001, 11:01 PM
  4. how do you make the X Y thing work?
    By bluehead in forum C++ Programming
    Replies: 2
    Last Post: 11-05-2001, 04:19 PM