Thread: Most readable way to organize variables and files?

  1. #1
    .........
    Join Date
    Nov 2002
    Posts
    303

    Most readable way to organize variables and files?

    Hi Im working on a library and I'm curious as to whats the most readable way to organize things. Currently I have all my function definitions in one C file and all the variables used(except my defines, i have 2) declared in each function. My header file has all my function prototypes etc. I downloaded a few librarys off freshmeat to try and get ideas of how to organize things and everyone does it different.

    Is it easier to read if All the functions are in one file, or maybe put each in a seperate file? Also is it easier to read if I put variables that are used in more than one function in a structure? I know everyone does it different just curious as to whats the recommended way of doing this. I want to keep it as readable as possible for myself because it's starting to get bigger, and for anyone who might actually use it. How do you guys usually organize stuff? Any and all comments would be great

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    In principle, you have

    lib.h
    This contains all the public interfaces to your library, consisting mostly of function prototypes, structures and #defines. Ideally, no variables should be in here.

    Later on, if things get really large, you may choose to split this up, so that lib.h includes say lib-api.h and lib-tools.h

    lib.h is the only file which users of your library ever see - apart from the library itself. Though they may find a read-only copy of the source code useful with a debug version of the library.

    private.h
    This contains all the public information which needs to be shared internally to your library, but which is hidden from the users of your library.

    This too can be broken down into many files later on.

    C++ has namespaces for hiding names from the user. In C, a common technique is to prefix all global symbols with a short (2 to 4) string. Eg OpenGL uses "gl" as it's common prefix.

    Not only does this help to identify your library, it also helps when you want to implement a routine with a common name like read()

    Within each source file, make as many things as you can 'static'. This localises the scope of the symbol to be just in that source file. This helps no end in figuring out what the dependencies are.

    Even though you're writing in C, it helps to organise things on a C++ line - like grouping common functions into the same source file, and using a header file to describe the interface to that source file (like you would with a C++ class.h and it's implementation class.cpp)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    .........
    Join Date
    Nov 2002
    Posts
    303
    Hey thanks for the reply, thats way different from what I was doing. My library is gonna be a string and IO library so splitting them up like you said sounds like the perfect thing to do.
    But say I have mylib.h , mystring.h and myio.h
    and from mylib.h I include the other two.

    Then myio.c includes myio.h
    And then mystring.c includes mystring.h

    Ok now in each of those 2 seperate headers I'd put my function prototypes. Like the string function prototypes in mystring.h and the IO function prototypes inn myio.h, as well as all public stuff, like stuff the user can use. Would I need to put ALL my function prototypes in mylib.h also or just putting them in those seperate headers would be enough?

    Also If I had private stuff could I just make an extension to any of those header files, like if I had two structures that I used for my string library internally that are of no use to the user, could I declare them in say pmystring.h and include that from mystring.h? Am I right in assuming it works like that?

    Is this the proper way to include a header file from another header file?
    Code:
    /************mylib.h************/
    #ifndef MYLIB_H
    # define MYLIB_H
    
    #ifndef MYIO_H
    # include "myio.h"
    #endif /* MYIO_H */
    
    #endif /* MYLIB_H */
    /*********************************/
    
    /**********myio.h****************/
    #define MYIO_H
    
    /********************************/
    Sorry for all the questions it just seems like a really good way to organize things, and I've never done it like this before. Thanks for the reply

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well
    Code:
    /************mylib.h************/
    #ifndef MYLIB_H
    #define MYLIB_H
    #include <mystring.h>
    #include <myio.h>
    #endif /* MYLIB_H */
    Code:
    /**********myio.h****************/
    #ifndef MYIO_H
    #define MYIO_H
    /* All myio public stuff */
    #endif /* MYIO_H */
    /********************************/
    If you want to make sure that they only include mylib.h and don't sneak around and directly include myio.h, then do something like this
    Code:
    /************mylib.h************/
    #ifndef MYLIB_H
    #define MYLIB_H
    #include <mystring.h>
    
    /* check myio was not included already from somewhere else */
    #ifdef MYIO_H
    #error Don't include myio.h yourself, only include mylib.h
    #endif
    #include <myio.h>
    #endif /* MYLIB_H */
    
    /**********myio.h****************/
    #ifndef MYIO_H
    #define MYIO_H
    
    /* were we included from mylib? */
    #ifndef MYLIB_H
    #error myio.h included without mylib.h
    #endif
    
    /* All myio public stuff */
    #endif
    /********************************/
    OK, they may figure out that
    #define MYLIB_H
    #include <myio.h>
    works, but then you have a real excuse to use this


    > just putting them in those seperate headers would be enough?
    That would be enough

    > could I declare them in say pmystring.h and include that from mystring.h?
    Putting them in pmystring.h is good
    #include "pmystring.h" in mystring.h is bad
    It kinda offers temptation to the more curious library user to go looking inside pmystring.h to see what goodies there are.

    Your source code should be like this
    Code:
    /* mystring.c */
    #include <mylib.h>  // gotta obey your own rules
    #include "pmystring.h"  // our private stuff
    ...
    Here's a bit more on nested include files
    http://www.eskimo.com/~scs/cclass/int/sx6b.html

    I think it's OK to use nested includes in your lib.h, since this makes it simple for your users to
    #include <mylib.h>
    and not worry about what else they need to include.

    But I would stay away from
    Code:
    /* mystring.c */
    #include "everything.h"
    ...
    as a means of saving yourself a bit of typing. In a large project, such techniques create far too many pseudo-dependencies, which cause tools like "make" to recompile a whole bunch of stuff which didn't need recompling.
    It also makes it difficult for you to figure out "what does this module depend on" if you're planning any porting or re-use of code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    .........
    Join Date
    Nov 2002
    Posts
    303
    OK, they may figure out that
    #define MYLIB_H
    #include <myio.h>
    works, but then you have a real excuse to use this
    Lol yea.

    Thanks a ton I completely understand everything now and know exactly how to do it. That is a pretty sneaky way of using defines and I don't think I would have ever figured it out on my own. It is an awesome explanation and I think it should be added to the FAQ, or an entry like that should be added. I noticed it was on the to-do list heh. I did alot of searching and just ended up finding info on using ifndef to making header files idempotent and alot of other useful stylistic things like this. Nothing explained how to use multiple header files in that way, they usually only showed one example. Again thanks this has been a great help.

    Oh also I took your advice and made all my variables for my IO functions static to the same C file. After going throught it all I realized I was using every variable in at least 3 different functions so I made them all static. It made it
    way easier to read. Thanks again.
    Last edited by SourceCode; 04-19-2003 at 02:34 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static variables and header files
    By drrngrvy in forum C++ Programming
    Replies: 8
    Last Post: 12-02-2006, 01:27 PM
  2. Replies: 3
    Last Post: 11-28-2006, 03:44 PM
  3. Variables in header files
    By Overlord in forum C++ Programming
    Replies: 5
    Last Post: 10-15-2006, 06:43 AM
  4. make variables visible on multiple files
    By jagerhans in forum C++ Programming
    Replies: 4
    Last Post: 08-28-2004, 06:32 PM
  5. variables across files
    By Hunter2 in forum C++ Programming
    Replies: 13
    Last Post: 07-23-2002, 10:58 AM