Thread: Code Management

  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    13

    Code Management

    Hi

    up untill now all the programs i've made are small enough to be writen in one C file.

    however, now i need to split the program into smaller parts so that i can actualy understand what is happening at different points.

    is there anyway to give each file access to structs from other files??

    i've figgured out how to do global variabls and functions (use of extern and prototypes)

    I'm using Borland C++ builder, with each C file in the project so they can talk to eachother well. i'm just stuck on typedefs

    any help would be much apreciated

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Here's how you give modules access to types and declarations in other modules:
    Code:
    /* mystruct.h */
    #ifndef MYSTRUCT_H
    #define MYSTRUCT_H
    
    typedef unsigned char byte;
    /* byte is a synonym for "unsigned char" */
    
    typedef struct _mystruct_t
    {
       byte a,b;
    } mystruct_t;
    /* mystruct_t is a synonym for "struct _mystruct_t" */
    
    void print_mystruct(const mystruct_t *ms);
    /* function delcaration so other modules can call this function */
    
    #endif /* MYSTRUCT_H */
    Code:
    /* mystruct.c */
    #include <stdio.h>
    #include "mystruct.h"
    
    void print_mystruct(const mystruct_t *ms)
    {
       printf("%d, %d\n",ms->a, ms->b);
    }
    Code:
    /* main.c */
    #include "mystruct.h"
    
    int main (void)
    {
       mystruct_t ms;
       ms.a = 1;
       ms.b = 2;
    
       print_mystruct(&ms);
    
       return 0;
    }
    gg

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    ok.

    given that code, how would you make it possible for mystruct.c to use typedefs in main.c?

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    If you have types that you want to make available to any module, then put them in their own .h file. If main.c and mystruct.c both want to use those types, then they will #include the .h file.

    gg

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Just nit-picking....

    In this:
    Code:
    typedef struct _mystruct_t
    {
       byte a,b;
    } mystruct_t;
    The _t normally denotes a typedef. In your code, the struct is tagged as _mystruct_t, when of course it isn't actually a typedef name, so the use of _t is inappropriate. Also, you're running very close to the naming restrictions by using a leading underscore, I'd suggest you avoid them altogether.

    My advice:
    Code:
    typedef struct mystruct
    {
       byte a,b;
    } mystruct_t;
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Where I grew up, "_t" stands for "type", and "struct _mystruct_t" is a type.

    I use leading underscores on my structure tags cuz MS does - any name collisions will be found at compile/link time anyway.

    What-ever floats your boat

    gg

  7. #7
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    ohh, ok

    so its imposible to put them in seperate files. realy stops just about all code management....

  8. #8
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    Read what codeplug said - you put shared declarations (typedefs, function prototypes, whatever) in a .h file, and #include it wherever you need it.
    that is what i want to stop. if you do that then its not realy dividing the code up real well is it?? its just sticking it in one file. i read what codeplug said, but it doesnt suit what i'm after. i'm beginning to suspect what i want cant be done....

  9. #9
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    no, i have a header file for each c file. the header files contain the prototypes, extern's and typedefs.

    the problem comes when i try to use one typedef in a procedure in a different c file. its basicly to do with the ordering of the header files. i need to know how to "prototype" a typedef. so that it doesnt stop with an error when it gets to one that is declaired later on.

  10. #10
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>so that it doesnt stop with an error when it gets to one that is declaired later on.
    Are you using the include guards as shown in the above posts?
    Code:
    /* This is file myheader.h */
    #ifndef MYHEADER
    #define MYHEADER
    
    /* Prototypes/typedefs etc go here */
    
    #endif
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  11. #11
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    ok, i apologise if i have been missleading in what i have said.

    i'm trying (note the trying) to make a RPG adventure game similar to diablo, arcanum etc, so i want to keep all the code in smallish files so that its extremely easy to find things.

    the problem comes when i deal with typedefs.

    this is only an example, the real problem is spread over 4 files - Items.h, spells.h, Monsters.h and Character.h. Each header file contains an extern statement for the global variables declared in the file, and the prototypes for the functions. then there is Global.h which is included in every c file

    basicly each file requires a typdef from another file, and nomatter what order they are placed in, atleast one typedef is required before it is declared


    Items.h
    --------------------------------------------------------
    #include "Global.h"
    #ifndef _Item.h_
    #define _Item.h_
    typedef struct
    {
    char * Name;
    int Damage;
    int Cost;
    CharacterPropertiesType Bonuses;
    }Itemtype;

    #endif



    Character.h
    ---------------------------------------------
    #include "Global.h"
    #ifndef _Global.h_
    #define _Global.h_
    typedef struct
    {
    int X;
    int Y;
    ItemType Item;
    } InventoryItemType;

    typedef struct
    {
    int HP;
    int MP;
    int Vit;
    int Str;
    } CharacterPropertiesType;
    #endif

    Global.h
    ------------------------------------------------------
    #include "Character.h"
    #include "Item.h"

    I keep the different typedefs in these files because thats what they relate to. This way is easier to change things (such as adding a new stat for the character, say Intelegence or something) because its under character.h and is only declared once.

    if there is a way to make this work i would be most apreciative, but if not, any other suggestions would be handy. (and please dont say "wack it all in one header file, coz thats what i'm trying to stop)

    Thx

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You are going to have a hard time maintaining header files that depend on each other like that. There is nothing wrong with having multiple .c files for a single .h file.

    Having said that:
    • Macro's can't have a period in them - they follow the same rules as for variable names. "_Item.h_" -> "_Item_h_"
    • You declared "Itemtype", but referenced it as "ItemType"
    • Your individual header files should not include Global.h, Global.h is a convenience header to be used by application programs, not your library. A general rule of thumb is "only include header files that contain definitions that you need.
    • Which leads us to your double-dependency problem. Items.h needs types in Character.h, and Character.h needs types in Items.h. To make this work (even though I don't agree with the design) you have to pick one repugnancy to keep, and eliminate the other dependency using forward declarations.
      In this example, we'll keep the "Character.h needs Items.h" dependency.
      Code:
      #ifndef _Character_h_
      #define _Character_h_
      
      /* pull in definitions in Items.h */
      #include "Items.h"
      
      typedef struct
      {
          int X;
          int Y;
          ItemType Item;
      } InventoryItemType;
      
      typedef struct tag_CharacterPropertiesType
      {
          int HP;
          int MP;
          int Vit;
          int Str;
      } CharacterPropertiesType;
      
      #endif
      Code:
      #ifndef _Item_h_
      #define _Item_h_
      
      /* forward delcaration since Character.h includes us! */
      struct tag_CharacterPropertiesType;
      
      typedef struct
      {
          char * Name;
          int Damage;
          int Cost;
          struct tag_CharacterPropertiesType *Bonuses;
      } ItemType;
      
      #endif
      A few things to notice here:
      - You have to have a structure tag for the CharacterPropertiesType typedef. This is because you can't have a forward declaration of a typedef.
      - There is limited use of a forward declaration:
      - You can only use it as a pointer (ie. the size of the forwarded declaration is not needed)
      - You can not access any elements of the forwarded type

      You should make all the individual header files private to your library and only expose Global.h since this method creates include dependencies. For example, an application can't just include Item.h - it will have to include Character.h as well in order to be able to use the Bonus pointer. These types of details are hidden in Global.h (I would rename Global to <your library name>)


    gg

  13. #13
    Registered User
    Join Date
    Mar 2003
    Posts
    13
    ok, thanks for you help, this is exactly what i'm looking for. i realise that there is no problem with using 1 header file for more than one c file, its just that i find the way i've currently got it set out much easier to navigate through, up untill now.

    Thx about the _item_h_ period thing, never realised that you couldn't do that, but strangely everything's worked up till now.

    one last question, what are forward declarations? i dont like using something that i dont understand.

    and once again, Thanks for your help

  14. #14
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>#define _Item_h_
    Now you've gone and done it You've used a reserved name for sure this time

    All names starting with an underscore followed by another underscore or an upper case letter are reserved for implementation use.

    As this is a C forum, not an MS one, we should try and stick to the rules, imho. Else your boat might not float when it is supposed to!
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    A forward declaration is a way of telling the compiler:

    "Hey! compiler, you don't know anything about this type (size or members) - but you will, so compile this and shut up!"

    As I said before, this basically limits you to only using the type as a pointer since a pointer is just a memory address.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Proposal: Code colouring
    By Perspective in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 05-14-2007, 07:23 AM
  2. Choosing a compiler
    By pushingsquares in forum Game Programming
    Replies: 27
    Last Post: 12-14-2006, 10:33 AM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Updated sound engine code
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-18-2004, 12:38 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM