Re: Big projects divided into modules and sub-modules

Discussion in 'C Programming' started by ImpalerCore, Mar 10, 2011.

  1. ImpalerCore

    ImpalerCore Guest

    On Mar 9, 3:33 pm, pozz <> wrote:
    > Recently I started creating bigger and bigger C projects, consequently I
    > started searching for a good method to organize the complex code.
    > I like to divide the big problem (the application) into several tasks or
    > modules. Each module has a logical function in the application and I try
    > to create it as indipendent as possible respect the rest of the
    > application (other modules).
    > So I separate the implementation of the module (the code in the .c file)
    > and the interface with the external world (the code in the .h file).
    > This is inspired from object oriented programming.
    > In the related include file of the module, I write custom types
    > (structs, enums, typedefs, unions), #defines and function prototypes. I
    > tend to avoid extern variables in favor of function (so the external
    > world hasn't to know the implementation details about the variable).
    > I think this approach is fine and I used it with success in the past.
    > But now I think it is too limited in my new bigger applications. I'll
    > try to explain my new difficulties.
    > In a big project I'd like to divide modules in sub-modules and maybe in
    > sub-sub-modules. For example, suppose you have to code a TCP/IP stack.
    > It is a very hard work and a complex application.
    > I can start to create some modules, one for each layer: one for TCP and
    > one for IP.
    > Now you start writing some code lines in tcp module (tcp.c) and soon you
    > note that the file start becoming too big. So you decide, for example,
    > to divide the tcp_in and tcp_out module (one for incoming packets and
    > one for outgoing packets).
    > You start coding in tcp_in.c and tcp_out.c, but you have a single
    > interface with the external world, so maybe you can have three files:
    >    tcp_in.c
    >    tcp_out.c
    >    tcp.h
    > Most probably, tcp_in and tcp_out should share some status informations
    > or similar things. What to do now? It should be better to define
    > external variables (accessed in tcp_in.c and tcp_out.c at the same time)
    > or to maintain the OOP paradigm and define several function for every
    > single piece of shared information/variable?
    > In embedded world with not so good optimizers, function calls will be
    > converted in CALL assembler instructions, so introducing a certain delay
    > (respect accessing external variables) just to have a better
    > organization in the code.
    > At the contrary, external variables (maybe declared in tcp.h) are
    > dangerous and are outside the OOP paradigm.
    > I'm sorry for this long post, but I hope to have some ideas and
    > suggestions from you about my doubts.

    From my experience, there have been a couple of different module
    source architectures I've used for development. The first is using a
    single pair of corresponding .h/.c files. It's advantage is that
    during initial development, one can focus on functionality and API
    without the complexity of multi-file dependencies. If you want to
    change a function name, there's less hassle you have to go through in
    my opinion. This is what I use when prototyping a new module.

    As you say, when the module grows, the header and source can get quite
    long. I have some that range up to 4K lines of code. While I don't
    mind long source files, searching through long headers to try to find
    a particular API function (when you don't know exactly what you need)
    is quite tedious. To this end, I use doxygen to create a web
    interface that allows me to easily navigate a module's API
    documentation rather than scanning through header files. Having some
    auto-generated web documentation quickly becomes more useful the more
    modules you have to maintain and how long it's been since you've
    maintained that module. Headers are still one long file, but the web
    interface makes browsing API functions much more pleasant.

    As a module matures, you focus less and less on functionality and more
    on presentation. This is where you might start thinking of public and
    private interface, like the _impl.h headers already mentioned. One
    can also decompose source files into multiple pieces, but the
    potential drawback is that it can push more complexity into the build
    system. Depending on the number of modules, one can get into the
    discussion of how to group modules into libraries to reduce
    dependencies and make them more standalone.

    Just some ideas to percolate on.

    Best regards,
    John D.
    ImpalerCore, Mar 10, 2011
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben
  2. Shaguf
    Dec 24, 2008
  3. Shaguf
    Dec 26, 2008
  4. Shaguf
    Dec 26, 2008
  5. Shaguf
    Dec 24, 2008

Share This Page