Methods for understanding complex, real world, C++ code?

Discussion in 'C++' started by mathog, Apr 10, 2012.

  1. mathog

    mathog Guest

    Mostly when I program it is maintenance work - making little tweaks and
    corrections to other people's code. The C++ books and tutorials are all
    clear and wonderful about objects and methods but they only ever give
    toy examples. In real world programs it seems that the code is always a
    morass of object types and methods, often with similar names.
    (Resulting in: "yes, 'print', but which 'print'?"). I find it extremely
    difficult to find in such code where actions actually occur, or in many
    cases what earlier events led to an issue later in the program.

    Presumably there are tools to help with this that I should be using but
    am not. What are these tools? If somebody knows of a tutorial or
    reference on how to deal with complex code like this, please share it.

    For instance, lately I have had to make some changes to Inkscape. The
    development environment is Mingw. This program uses Cairo, GDK, GTK,
    Pango, and heaven knows what else, in addition to all of its own code.
    The closest thing I have to a class browser is the doxygen web
    interface, example:

    http://fossies.org/dox/inkscape-0.48.3.1/clipboard_8cpp_source.html

    One of the tasks on my "to do" list is to add import/export of images to
    the EMF extension. I found the relevant sections in the EMF extension
    (switch() cases provided, but no code in them) by a grep through all of
    the source code for the EMF keyword function associated with images.
    Looking around for an example of how to handle images in Inkscape
    located the link above by more grep's, since I knew one could paste an
    image into the program from the clipboard. From this link, on line 937
    we see that rather than converting directly from GDK::pixbuf to an
    Inkscape object type they punted. First they save from the Pixbuf to a
    PNG file, and then they use a preexisting file_import function to read
    that object back in. The program pastes at the cursor (or something like
    "at the cursor") but how it knows where that is lies in a code segment
    far far away. Anyway, this illustrates the point I'm trying to make.
    One would imagine that somewhere in this heap of code there is a
    "create/import image of size W,H at position X,Y", but good luck finding it.

    Figuring out the logic in real C++ programs is also challenging. In
    Inkscape, for instance, much of the program is event driven, so a
    backtrace will often not tell you what happened before a given execution
    point. Example:

    A ->
    B ->
    C (configure: event X will cause E) ->
    D (configure: something else relevant when E runs) ->
    C ->
    B (event X) ->
    E (stops at preset breakpoint)

    So the back trace shows

    A->B->E

    and there is no clue that C and D are important, or even that they ever
    ran. This A->E example is grossly simplified, since in the real program
    there were thousands of function calls before event X. Short of tracing
    every function call how would one ever know that C,D need to be looked at?

    Thank you,

    David Mathog
     
    mathog, Apr 10, 2012
    #1
    1. Advertising

  2. mathog

    K. Frank Guest

    Re: Methods for understanding complex, real world, C++ code?

    Hi David!

    On Apr 10, 11:54 am, mathog <> wrote:
    > Mostly when I program it is maintenance work - making little tweaks and
    > corrections to other people's code.  The C++ books and tutorials are all
    > clear and wonderful about objects and methods but they only ever give
    > toy examples.  In real world programs it seems that the code is always a
    > morass of object types and methods, often with similar names.
    > (Resulting in: "yes, 'print', but which 'print'?"). I find it extremely
    > difficult to find in such code where actions actually occur, or in many
    > cases what earlier events led to an issue later in the program.


    First off, "We Share Your Pain!"

    By the way, you should be aware of the Microsoft WSYP program
    for improving user experience:

    http://www.youtube.com/watch?v=3dF-POFE30E


    > Presumably there are tools to help with this that I should be using but
    > am not. What are these tools?  If somebody knows of a tutorial or
    > reference on how to deal with complex code like this, please share it.


    A couple of comments:

    Much real-world code isn't that good. It may be that the
    programmers who wrote it weren't that good. It may be that
    the programmers were great, but the code grew and evolved
    over time, obscuring what was originally a good design, and
    that the (possibly rational) decision was made not to refactor
    the code base and clean up the current design.

    Also, good real-world code is often (very) complicated. Many
    real-world problems are inherently complicated. So the art
    of good programming is not to eliminate complexity (you can't),
    but to master that complexity in as organized a way as you can.

    Further, as you point out, many programming books aren't realistic.
    It's legitimate to use toy examples -- otherwise the books would
    become unreadably long -- but authors often leave out (purposely?)
    real-world complexity that their favorite design methodology
    doesn't handle well.

    So ... Welcome to the real world.

    How to deal with this? I don't have a good or simple answer.

    What I do is try to get an overview of the code -- or, better,
    the part of the code that is relevant to what I am doing. I
    try to get a feel for its "shape," for lack of a better word.
    Then I rely on intuition to zero in on where the action (relevant
    to my problem) is.

    (I know, I know ... This is hardly useful advice.)

    Only at this point is it practical to look at the details.
    (One can "look at details" by reading the code, running a
    debugger, putting in print statements, or otherwise adding
    instrumentation, according to one's taste. My preference
    is to use a combination of reading the code and adding print
    statements, but the exact technique doesn't really matter.)

    It's hard, it's challenging, and I can't give you a detailed
    recipe for how to do it, because for me, there's a lot of
    intuition involved.

    In my experience it's a rare talent for a developer to be able
    to work effectively with a large, unfamiliar code base.

    I liken it to the Radar O'Reilly character in the M.A.S.H.
    story (movie, TV, etc.). The joke with him is that he'd
    look up and say "Choppers." and then only after a few minutes
    had passed would the other characters hear the choppers
    flying in to deliver the wounded.

    In my experience there is a minority of developers who, when
    looking for a bug in "Other People's Code," have -- like
    Radar O'Reilly -- some sort of sixth sense for where the
    bodies are buried. And they are worth their weight in gold.

    The only concrete advice I can give you is to gain (a lot
    of) experience in working with large, unfamiliar code bases.
    The more you see various chunks of code written by programmers
    with differing styles and levels of talent, the more easily
    you'll be able to recognize at a higher level what they're
    trying to do, before drilling down into the details.

    To give an overly simplistic "toy" example, when I look at
    code I can say "Oh, this guy's using a bunch of nested if
    statements." or "This guy's using a switch statement." or
    "This guy's using virtual functions in a bunch of derived
    classes." or "This guy's setting up a look-up table." all
    to accomplish the same programming task. In this context
    it doesn't matter whether a specific technique is "right"
    or "wrong" or 'better" or 'worse," so it's not worth
    arguing about. In practice you will see all manner of
    code, and you need to be able to recognize what the guy
    is trying to do whether or not he is doing it "right."

    > For instance, lately I have had to make some changes to Inkscape...
    > ...
    > Figuring out the logic in real C++ programs is also challenging.  In
    > Inkscape, for instance, much of the program is event driven, so a
    > backtrace will often not tell you what happened before a given execution
    > point.  Example:
    >
    > A ->
    > B ->
    > C (configure: event X will cause E) ->
    > D (configure: something else relevant when E runs) ->
    > C ->
    > B (event X) ->
    > E (stops at preset breakpoint)
    >
    > So the back trace shows
    >
    > A->B->E
    >
    > and there is no clue that C and D are important, or even that they ever
    > ran.


    Yes, you're absolutely right about this. Working with
    event-driven (sometimes called "reactive") programming
    is especially hard. Trying to understand "Other People's
    Code" becomes even more difficult because, as you point
    out, traditional procedural techniques such as reading
    one line of code after another or stepping through
    execution with a debugger don't map well to the actual
    event-driven logic. At some point you have to hope for
    the good fortune that the original programmer approached
    his event-driven design in a thoughtful and well-organized
    manner.

    When I _write_ event-driven code, I tend to instrument it
    with print statements that include a tag that indicates
    which _logical_ process a particular step belongs to. So
    in your example, although the backtrace would show:

    A->B->E

    my print-statement log file would show:

    Process-Q: A
    Process-Q: B
    Process-Q: C: handle event X; schedule E
    Process-Q: D: configure some property of E
    Process-Q: E: (stops at some breakpoint)

    Sometimes you can retroactively instrument existing code along
    these lines, but often it's not practical.

    > This A->E example is grossly simplified, since in the real program
    > there were thousands of function calls before event X.  Short of tracing
    > every function call how would one ever know that C,D need to be looked at?


    Very hard. You need to develop that Radar O'Reilly sixth sense,
    or you need to (partially) instrument the code along the lines
    described above. And if the code isn't naturally organized
    into logical sequences of event processing, it can get pretty
    nasty.

    > Thank you,


    I apologize that I haven't offered any particularly good
    recipe for tackling these issues. I would love to hear
    what other folks think, and what procedures and tools they
    use for these kinds of challenges.

    The problem is that when dealing with "Other People's Code,"
    you have to work with the code as it is, rather than as you
    would wish it to be.

    > David Mathog



    Good Luck ... And Happy (OPC) Hacking!


    K. Frank
     
    K. Frank, Apr 10, 2012
    #2
    1. Advertising

  3. mathog

    Ian Collins Guest

    On 04/11/12 03:54 AM, mathog wrote:
    > Mostly when I program it is maintenance work - making little tweaks and
    > corrections to other people's code. The C++ books and tutorials are all
    > clear and wonderful about objects and methods but they only ever give
    > toy examples. In real world programs it seems that the code is always a
    > morass of object types and methods, often with similar names.
    > (Resulting in: "yes, 'print', but which 'print'?"). I find it extremely
    > difficult to find in such code where actions actually occur, or in many
    > cases what earlier events led to an issue later in the program.
    >
    > Presumably there are tools to help with this that I should be using but
    > am not. What are these tools? If somebody knows of a tutorial or
    > reference on how to deal with complex code like this, please share it.


    I use Oracle's version of NetBeans (Solaris studio) which has pretty
    good code browsing capabilities. Standard NetBeans or Eclipse should do
    much the same.

    --
    Ian Collins
     
    Ian Collins, Apr 10, 2012
    #3
  4. mathog

    Jorgen Grahn Guest

    On Tue, 2012-04-10, mathog wrote:
    > Mostly when I program it is maintenance work - making little tweaks and
    > corrections to other people's code. The C++ books and tutorials are all
    > clear and wonderful about objects and methods but they only ever give
    > toy examples. In real world programs it seems that the code is always a
    > morass of object types and methods, often with similar names.
    > (Resulting in: "yes, 'print', but which 'print'?"). I find it extremely
    > difficult to find in such code where actions actually occur, or in many
    > cases what earlier events led to an issue later in the program.
    >
    > Presumably there are tools to help with this that I should be using but
    > am not. What are these tools? If somebody knows of a tutorial or
    > reference on how to deal with complex code like this, please share it.


    I don't have specialized tools, but here are some I actually use. They
    may be Unix-specific.

    - Emacs with 'exuberant ctags' in C++ mode. Still won't work well
    for looking up overloaded names though :-(

    - Doxygen with full graph generation enabled.

    - A gprof profiling run of the code, compiled with inlining disabled.
    Not for the profiling but for showing the main code flows.

    - The nm(1) symbol lister to get a rough idea what one source file
    contains and what it depends on.

    - Pen and paper for reconstructing class diagrams, state machines etc.

    - Valgrind for detecting obvious memory handling bugs.

    - Changing the code (making things private or const; changing their
    type and so on) just to see what stops compiling. Works best if your
    Makefile isn't broken, so the right things are rebuilt automatically.

    BTW, I think most of these problems are not related to C++. Most are
    there in C too. (Exception: inheritance. I really hate debugging messy
    code where everything is badly designed run-time polymorphism and
    nothing is documented.)

    And, like K. Frank I share your pain. Remember that in maintenance
    programming, at least you're creating stuff which people *really need*
    and are asking for. New code on the other hand is often not used in
    the end.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Apr 10, 2012
    #4
  5. mathog

    Guest

    On Tuesday, April 10, 2012 5:54:39 PM UTC+2, mathog wrote:
    > In real world programs it seems that the code is always a
    > morass of object types and methods, often with similar names.


    I consider real world code that does not come with sufficient documentationto have a value close to zero. Often its less work to rewrite the stuff from scratch.

    In cases where this is not an option and pressure to bother is gross, I'd recommend to reverse engineer an UML model for the code, i.e. start with a static class model depicting interfaces, inheritance and aggregation, and continue by filling in usage information who calls what else. It may also possible to group classes to components.

    Once this is done, you can analyze method by method and add diagrams for the code's dynamics (sequence-, activity-, state diagrams). Whatever you findout you should also add as extra comments to the code.

    If you're lucky, you end up with a usable code documentation. Many times you won't be lucky, in spite of the systematic approach.

    Doxygen in combination with GraphViz is a good start if you are looking fortools. It will spare you of lots of manual work for the analysis. For modelling UML I prefer Sparxsystem's Enterprise Architect. It is a commercial product but relatively cheap compared to other tools. For reengineering purposes you'd need the "Professional" edition or better; its code-to-model import features should come handy.

    best,

    MiB.
     
    , Apr 11, 2012
    #5
  6. mathog

    K. Frank Guest

    Re: Methods for understanding complex, real world, C++ code?

    Hello Jorgen!

    On Apr 10, 6:26 pm, Jorgen Grahn <> wrote:
    > On Tue, 2012-04-10, mathog wrote:
    > > ...
    > > I find it extremely
    > > difficult to find in such code where actions actually occur, or in many
    > > cases what earlier events led to an issue later in the program.

    >
    > > Presumably there are tools to help with this that I should be using but
    > > am not. What are these tools?  If somebody knows of a tutorial or
    > > reference on how to deal with complex code like this, please share it.

    >
    > I don't have specialized tools, but here are some I actually use. They
    > may be Unix-specific.
    >
    > - Emacs with 'exuberant ctags' in C++ mode. Still won't work well
    >   for looking up overloaded names though :-(


    I'm a big fan of using ctags with emacs, although some people find
    emacs to be an acquired taste.

    > ...
    > - Changing the code (making things private or const; changing their
    >   type and so on) just to see what stops compiling. Works best if your
    >   Makefile isn't broken, so the right things are rebuilt automatically.


    I've only ever done this by accident, but I like this idea as a
    systematic
    technique. Maybe I'll add it to my bag of tricks.

    > ...
    > Remember that in maintenance
    > programming, at least you're creating stuff which people *really need*
    > and are asking for.  New code on the other hand is often not used in
    > the end.


    Hear, hear! Sometimes confusing code started out bad, but lots
    of times it starts out good, and the bloat and convolution and
    bit-rot you're struggling with came about because the code was
    useful and being used and growing and gaining new features
    because people wanted it. When you find yourself working on a
    multi-man-decade code base like this, it's actually kind of
    cool (if frustrating).

    > /Jorgen



    Thanks for your thoughts and suggestions.


    K. Frank
     
    K. Frank, Apr 11, 2012
    #6
  7. mathog

    Guest

    Re: Rewrite it. 

    On Wednesday, April 11, 2012 12:31:03 AM UTC+1, (unknown) wrote:
    > 
    > Re: &quot;Methods for understanding complex, real world, C++&quot;
    >
    > Rewrite it. That's what I do.
    > </pre>


    my boss tends not to give me the time to re-write 750 KLOC when a one line change is required. Get real.
     
    , Apr 11, 2012
    #7
  8. mathog

    Rui Maciel Guest

    wrote:

    > On Tuesday, April 10, 2012 5:54:39 PM UTC+2, mathog wrote:
    >> In real world programs it seems that the code is always a
    >> morass of object types and methods, often with similar names.

    >
    > I consider real world code that does not come with sufficient
    > documentation to have a value close to zero. Often its less work to
    > rewrite the stuff from scratch.


    This approach doesn't appear to be very reasonable. If a piece of code
    which may not be documented is already mature then your suggestion to
    reinvent the wheel may end up needlessly reintroducing bugs and other
    issues. So, just because you can't access the documentation of a piece of
    code you risk ending up needlessly wasting resources to make something worse
    than it already is. And where's the added value in this?


    Rui Maciel
     
    Rui Maciel, Apr 11, 2012
    #8
  9. mathog

    Rui Maciel Guest

    Re: Rewrite it. 

    wrote:

    > my boss tends not to give me the time to re-write 750 KLOC when a one line
    > change is required. Get real.


    Indeed.

    I wonder if these proponents of this type of scorched earth approach to
    documentation also believe it is a good idea to demolish their house and
    rebuild it if they can't find its blueprints.


    Rui Maciel
     
    Rui Maciel, Apr 11, 2012
    #9
  10. mathog

    Guest

    Re: Rewrite it. 

    On Wednesday, April 11, 2012 10:06:19 AM UTC+1, Rui Maciel wrote:
    > wrote:


    > > my boss tends not to give me the time to re-write 750 KLOC when a one line
    > > change is required. Get real.

    >
    > Indeed.
    >
    > I wonder if these proponents of this type of scorched earth approach to
    > documentation also believe it is a good idea to demolish their house and
    > rebuild it if they can't find its blueprints.


    I'm guessing they're thinking of someting "really large" they've encountered which they could re-write from scratch in 48 hours if they drank enough Jolt.
     
    , Apr 11, 2012
    #10
  11. mathog

    Noah Roberts Guest

    Re: Methods for understanding complex, real world, C++ code?

    On Apr 10, 12:55 pm, "K. Frank" <> wrote:

    > Yes, you're absolutely right about this.  Working with
    > event-driven (sometimes called "reactive") programming
    > is especially hard.  Trying to understand "Other People's
    > Code" becomes even more difficult because, as you point
    > out, traditional procedural techniques such as reading
    > one line of code after another or stepping through
    > execution with a debugger don't map well to the actual
    > event-driven logic.  At some point you have to hope for
    > the good fortune that the original programmer approached
    > his event-driven design in a thoughtful and well-organized
    > manner.


    I'm currently having some trouble with people complaining about my
    code. Having worked with event programming for years among
    programmers who find it as straight forward as I do, I'm having a very
    hard time it seems to express things in a way that others understand.
    I've made UML diagrams to try and alleviate the problem, but they
    don't look at them. I used doxygen to generate comments for
    everything. I used standard constructs like function<>, bind(),
    etc...but they find them confusing.

    To me, in OO the event driven or observer architecture is completely
    natural. You have objects that say, "I got something happening over
    here!!" and you have other objects saying, "I hear you!" You map out
    what's going to happen by looking at the connections. If ordering is
    important you may have to learn the specific nature of a given event
    system to figure out what, exactly will happen and when...but
    generally you just look to see that things will happen and in what
    order isn't as important (in fact usually you only have one listener
    attached to any single source).

    Further, to me anyway, it allows you to fully understand one part of
    the program knowing that it does some things, tracks a resource or
    pipe or something, and then generates events for others to observe.
    You don't need to know what's going to happen then to fully understand
    everything there is to understand about that. I find that much easier
    to understand than trying to follow a spaghetti of traces to this and
    that.

    I've written trace logs for EVERYTHING. If you turn on trace in the
    log it will very rapidly take up huge amounts of space spewing out
    every function call that's happening. It's multithreaded though so
    it's hard to say what order is happening. I used log4cplus so that we
    can turn on and off various logs that are named by class.

    Now I'm being asked by my manager to comment every line of code
    basically. He's been around longer than I have but this still seems
    very strange to me.

    What can be done to bridge the gap so that "procedural" programmers
    can keep up?
     
    Noah Roberts, Apr 11, 2012
    #11
  12. mathog

    Lynn McGuire Guest

    Re: Methods for understanding complex, real world, C++ code?

    On 4/11/2012 11:23 AM, Noah Roberts wrote:
    > On Apr 10, 12:55 pm, "K. Frank"<> wrote:
    >
    >> Yes, you're absolutely right about this. Working with
    >> event-driven (sometimes called "reactive") programming
    >> is especially hard. Trying to understand "Other People's
    >> Code" becomes even more difficult because, as you point
    >> out, traditional procedural techniques such as reading
    >> one line of code after another or stepping through
    >> execution with a debugger don't map well to the actual
    >> event-driven logic. At some point you have to hope for
    >> the good fortune that the original programmer approached
    >> his event-driven design in a thoughtful and well-organized
    >> manner.

    >
    > I'm currently having some trouble with people complaining about my
    > code. Having worked with event programming for years among
    > programmers who find it as straight forward as I do, I'm having a very
    > hard time it seems to express things in a way that others understand.
    > I've made UML diagrams to try and alleviate the problem, but they
    > don't look at them. I used doxygen to generate comments for
    > everything. I used standard constructs like function<>, bind(),
    > etc...but they find them confusing.
    >
    > To me, in OO the event driven or observer architecture is completely
    > natural. You have objects that say, "I got something happening over
    > here!!" and you have other objects saying, "I hear you!" You map out
    > what's going to happen by looking at the connections. If ordering is
    > important you may have to learn the specific nature of a given event
    > system to figure out what, exactly will happen and when...but
    > generally you just look to see that things will happen and in what
    > order isn't as important (in fact usually you only have one listener
    > attached to any single source).
    >
    > Further, to me anyway, it allows you to fully understand one part of
    > the program knowing that it does some things, tracks a resource or
    > pipe or something, and then generates events for others to observe.
    > You don't need to know what's going to happen then to fully understand
    > everything there is to understand about that. I find that much easier
    > to understand than trying to follow a spaghetti of traces to this and
    > that.
    >
    > I've written trace logs for EVERYTHING. If you turn on trace in the
    > log it will very rapidly take up huge amounts of space spewing out
    > every function call that's happening. It's multithreaded though so
    > it's hard to say what order is happening. I used log4cplus so that we
    > can turn on and off various logs that are named by class.
    >
    > Now I'm being asked by my manager to comment every line of code
    > basically. He's been around longer than I have but this still seems
    > very strange to me.
    >
    > What can be done to bridge the gap so that "procedural" programmers
    > can keep up?


    You can't. If a programmer does not understand
    event driven code then they will never transition
    to the new device driven interface model.

    Lynn
     
    Lynn McGuire, Apr 11, 2012
    #12
  13. mathog

    Jorgen Grahn Guest

    Re: Methods for understanding complex, real world, C++ code?

    On Wed, 2012-04-11, Noah Roberts wrote:
    > On Apr 10, 12:55 pm, "K. Frank" <> wrote:
    >
    >> Yes, you're absolutely right about this.  Working with
    >> event-driven (sometimes called "reactive") programming
    >> is especially hard.  Trying to understand "Other People's
    >> Code" becomes even more difficult because, as you point
    >> out, traditional procedural techniques such as reading
    >> one line of code after another or stepping through
    >> execution with a debugger don't map well to the actual
    >> event-driven logic.  At some point you have to hope for
    >> the good fortune that the original programmer approached
    >> his event-driven design in a thoughtful and well-organized
    >> manner.

    >
    > I'm currently having some trouble with people complaining about my
    > code. Having worked with event programming for years among
    > programmers who find it as straight forward as I do, I'm having a very
    > hard time it seems to express things in a way that others understand.
    > I've made UML diagrams to try and alleviate the problem, but they
    > don't look at them. I used doxygen to generate comments for
    > everything. I used standard constructs like function<>, bind(),
    > etc...but they find them confusing.
    >
    > To me, in OO the event driven or observer architecture is completely
    > natural. You have objects that say, "I got something happening over
    > here!!" and you have other objects saying, "I hear you!" You map out
    > what's going to happen by looking at the connections. If ordering is
    > important you may have to learn the specific nature of a given event
    > system to figure out what, exactly will happen and when...but
    > generally you just look to see that things will happen and in what
    > order isn't as important (in fact usually you only have one listener
    > attached to any single source).
    >
    > Further, to me anyway, it allows you to fully understand one part of
    > the program knowing that it does some things, tracks a resource or
    > pipe or something, and then generates events for others to observe.
    > You don't need to know what's going to happen then to fully understand
    > everything there is to understand about that. I find that much easier
    > to understand than trying to follow a spaghetti of traces to this and
    > that.
    >
    > I've written trace logs for EVERYTHING. If you turn on trace in the
    > log it will very rapidly take up huge amounts of space spewing out
    > every function call that's happening. It's multithreaded though so
    > it's hard to say what order is happening. I used log4cplus so that we
    > can turn on and off various logs that are named by class.
    >
    > Now I'm being asked by my manager to comment every line of code
    > basically. He's been around longer than I have but this still seems
    > very strange to me.
    >
    > What can be done to bridge the gap so that "procedural" programmers
    > can keep up?


    Talk to them and work together with them. If it's straightforward to
    you and they aren't stupid, they can ask the right questions and
    eventually understand the way you think.

    But it seems to me that if you use this kind of design /everywhere/,
    you're the one who should adjust. I've been doing this for many years,
    and I can't say I recognize the style you describe. Unless it's
    another way to say "state machine". Perhaps your application domain is
    different from mine.

    (Not that people generally understand *my* architectures ...)

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Apr 11, 2012
    #13
  14. mathog

    Joe keane Guest

    In article <jm1l4g$a6e$>, mathog <> wrote:
    >The C++ books and tutorials are all clear and wonderful about objects
    >and methods but they only ever give toy examples.


    This was one of my disappointments with college 'education'.

    They teach you how to write programs, from scratch, all by yourself,
    which are probably no more than ten pages long.

    Employers don't give a s--- about that, they want to know if you can
    grok an existing codebase, get up to speed, interact with the people who
    know about it, deal with people who are no longer there, and mentor the
    'new guys' so they can do something useful.
     
    Joe keane, Apr 11, 2012
    #14
  15. mathog

    Noah Roberts Guest

    Re: Methods for understanding complex, real world, C++ code?

    On Apr 11, 3:36 pm, (Joe keane) wrote:
    > In article <jm1l4g$>, mathog  <> wrote:
    > >The C++ books and tutorials are all clear and wonderful about objects
    > >and methods but they only ever give toy examples.

    >
    > This was one of my disappointments with college 'education'.
    >
    > They teach you how to write programs, from scratch, all by yourself,
    > which are probably no more than ten pages long.
    >
    > Employers don't give a s--- about that, they want to know if you can
    > grok an existing codebase, get up to speed, interact with the people who
    > know about it, deal with people who are no longer there, and mentor the
    > 'new guys' so they can do something useful.


    Perhaps one way of instructing classes then would be to shuffle up
    peoples' answers from one assignment, hand them out to the students,
    ask them to extend the code to do more stuff...and assign them the
    task of grading the code they were given to work with.

    I can see issues with it, but maybe some variation on that theme could
    be instructive?
     
    Noah Roberts, Apr 12, 2012
    #15
  16. mathog

    K. Frank Guest

    Re: Methods for understanding complex, real world, C++ code?

    Hi Noah!

    On Apr 11, 12:23 pm, Noah Roberts <> wrote:
    > On Apr 10, 12:55 pm, "K. Frank" <> wrote:
    >
    > > Yes, you're absolutely right about this.  Working with
    > > event-driven (sometimes called "reactive") programming
    > > is especially hard.
    > > ...

    >
    > I'm currently having some trouble with people complaining about my
    > code.  Having worked with event programming for years among
    > programmers who find it as straight forward as I do, I'm having a very
    > hard time it seems to express things in a way that others understand.
    > I've made UML diagrams to try and alleviate the problem, but they
    > don't look at them.  I used doxygen to generate comments for
    > everything.  I used standard constructs like function<>, bind(),
    > etc...but they find them confusing.
    > ...
    >
    > I've written trace logs for EVERYTHING.  If you turn on trace in the
    > log it will very rapidly take up huge amounts of space spewing out
    > every function call that's happening.  It's multithreaded though so
    > it's hard to say what order is happening.  I used log4cplus so that we
    > can turn on and off various logs that are named by class.


    One comment about the multi-threading: Some of my event-driven
    code is multi-threaded, and the events that drive a given
    logical-processing sequence often come in on several different
    threads. This can play havoc with the trace logs when several
    logical-processing sequences are going on simultaneously.

    This is the main reason I add a logical-process tag to my log
    messages. (I also like to add a time-stamp.) Now all I have
    to do is grep my log for, say, "Process-Q" and I get a pretty
    readable trace for Process-Q. (If, say, Process-P sends an
    important event to Process-Q, I can separately grep for
    "Process-P" to get the trace for Process-P, and use the
    time-stamps to cross-correlate the two traces. Or I can
    jointly grep for "Process-P" and "Process-Q" and get the
    combined Process-P--Process-Q trace properly sequenced.)

    Yeah, I know ... Pretty simple-minded. But, hey, it works.

    > ...
    >
    > What can be done to bridge the gap so that "procedural" programmers
    > can keep up?


    My advice would be to not use event-driven programming unless
    you need to. You mentioned some benefits of event-driven
    programming (that I would generally lump under the heading
    of "looser coupling") that are applicable in situations where
    event-driven programming isn't absolutely necessary. But I
    find event-driven programming enough harder that I think the
    cost outweighs the benefit when applied to problems that are
    basically procedural in nature.

    But when a problem is inherently event-driven in nature,
    event-driven programming is the only way to go. Even if
    you write procedural-style code, you're still doing
    event-driven programming, whether or not you admit it.

    And if you don't admit it, you're going to end up with
    nested if-then spaghetti code that will collapse under
    its own weight. You need to use explicit event-driven
    programming to master the fact that event-driven problems
    are inherently harder than procedural problems.

    So the way I look at it is using an event-driven style
    for a procedural problem is harder than using a procedural
    style. (So cut your colleagues a break, and write
    procedural code.) But using a procedural style for
    an event-driven problem is vastly harder -- almost
    impossible -- than using an event-driven style.
    (Trust me on this -- I've bit myself with this more
    times than I care to remember.)

    So use event-driven programming for event-driven problems.

    How to bridge the gap with your procedural colleagues?
    I guess it's an issue of education and gentle persuasion.

    Tell your colleagues (and your boss) "Look, this problem
    is really hard -- it's inherently event-driven and that
    makes it hard. Now this event-driven code that addresses
    the problem is harder to understand than some other code
    that isn't trying to address as hard a problem. But it's
    the problem that's hard, not the code."

    Maybe they buy it, and maybe they don't. But if they're
    set in their procedural ways and try to solve some
    event-driven problem with procedural code, they will
    probably fail, and maybe that will make them more open
    to your way of thinking.


    Good luck.


    K. Frank
     
    K. Frank, Apr 12, 2012
    #16
  17. mathog

    Miles Bader Guest

    Re: Building a "house" that you can live in for decades to come.

    @Jeff-Relf.Me writes:
    > Uncommented, <A hRef="http://Jeff-Relf.Me/X.CPP">my code</A> looks
    > like...


    Hey wait, isn't that a bit over the IOCCC size limit?! :O

    -miles

    p.s. To anybody who didn't bother following the link, do!
    [Tho I'm suspicious that the code was run through some sort of
    obfuscator...]

    --
    Omochiroi!
     
    Miles Bader, Apr 12, 2012
    #17
  18. Re: Methods for understanding complex, real world, C++ code?

    On 4/11/2012 11:23 AM, Noah Roberts wrote:
    > To me, in OO the event driven or observer architecture is completely
    > natural. You have objects that say, "I got something happening over
    > here!!" and you have other objects saying, "I hear you!" You map out
    > what's going to happen by looking at the connections. If ordering is
    > important you may have to learn the specific nature of a given event
    > system to figure out what, exactly will happen and when...but
    > generally you just look to see that things will happen and in what
    > order isn't as important (in fact usually you only have one listener
    > attached to any single source).


    > What can be done to bridge the gap so that "procedural" programmers
    > can keep up?


    I am very much for OO design and have been brought up under the strict
    discipline of this newgroup :) However, I have seen good things used in
    bad ways. Your description of the use of event being "natural" reminds
    me of a library I just got done debugging.

    Every single class in the library contained a custom wrapper for
    boost::bind, boost::asio, boost::thread, to make a "callback queue"

    No class called methods on another, they were all posting callbacks to
    this queue and then handling them. It made it a son of a bitch to debug.

    when I cleaned it up, it ran much faster and was much more
    maintanable...IMO anyway.


    Events make sense sometimes, but not all the time. Do not be one of
    those guys that uses some pattern in every situation, even when it's not
    warranted.
     
    Christopher Pisz, Apr 12, 2012
    #18
  19. mathog

    mathog Guest

    Re: Methods for understanding complex, real world, C++ code?

    Jorgen Grahn wrote:

    > Talk to them and work together with them. If it's straightforward to
    > you and they aren't stupid, they can ask the right questions and
    > eventually understand the way you think.


    Most likely the information that makes the code easy for the original
    programmer to understand exists nowhere else but inside that
    programmer's skull. If the code is event driven, and especially if the
    handling of those events does not pass through some sort of queue or
    other mechanism that funnels it through a single place in the code, then
    from the maintenance programmer's viewpoint they are dealing with
    spaghetti code, using events and handlers in place of goto's. This sort
    of code can be understood, of course, but one needs a complete list of
    the events that are handled, an overview of where each type of event may
    be encountered, and the handlers that may be called in each case. This
    is exactly the information often only found encoded in somebody else's
    synapses.

    If a project includes more than handful of source files it should have
    an architecture document, describing in natural language the way the
    whole thing works. The existence of this document should be noted in
    the README. Burying it without mention among thousands of other files
    pretty much negates the purpose of having it in the first place.

    Regards.

    David Mathog
     
    mathog, Apr 12, 2012
    #19
  20. mathog

    Pavel Guest

    Re: Methods for understanding complex, real world, C++ code?

    K. Frank wrote:
    > Hello Jorgen!
    >
    > On Apr 10, 6:26 pm, Jorgen Grahn<> wrote:
    >> On Tue, 2012-04-10, mathog wrote:
    >>> ...
    >>> I find it extremely
    >>> difficult to find in such code where actions actually occur, or in many
    >>> cases what earlier events led to an issue later in the program.

    >>
    >>> Presumably there are tools to help with this that I should be using but
    >>> am not. What are these tools? If somebody knows of a tutorial or
    >>> reference on how to deal with complex code like this, please share it.

    >>
    >> I don't have specialized tools, but here are some I actually use. They
    >> may be Unix-specific.
    >>
    >> - Emacs with 'exuberant ctags' in C++ mode. Still won't work well
    >> for looking up overloaded names though :-(

    >
    > I'm a big fan of using ctags with emacs, although some people find
    > emacs to be an acquired taste.

    Those use ctags with vim :). It does not have that taste and works reasonably
    well for overloaded names while there is less than 30-40 overloads..

    But ultimately, grep (or fgrep) is your only friend..

    -Pavel
    >
    >> ...
    >> - Changing the code (making things private or const; changing their
    >> type and so on) just to see what stops compiling. Works best if your
    >> Makefile isn't broken, so the right things are rebuilt automatically.

    >
    > I've only ever done this by accident, but I like this idea as a
    > systematic
    > technique. Maybe I'll add it to my bag of tricks.
    >
    >> ...
    >> Remember that in maintenance
    >> programming, at least you're creating stuff which people *really need*
    >> and are asking for. New code on the other hand is often not used in
    >> the end.

    >
    > Hear, hear! Sometimes confusing code started out bad, but lots
    > of times it starts out good, and the bloat and convolution and
    > bit-rot you're struggling with came about because the code was
    > useful and being used and growing and gaining new features
    > because people wanted it. When you find yourself working on a
    > multi-man-decade code base like this, it's actually kind of
    > cool (if frustrating).
    >
    >> /Jorgen

    >
    >
    > Thanks for your thoughts and suggestions.
    >
    >
    > K. Frank
     
    Pavel, Apr 13, 2012
    #20
    1. Advertising

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. vijay
    Replies:
    8
    Views:
    729
  2. thermate
    Replies:
    0
    Views:
    293
    thermate
    Jan 27, 2008
  3. Hans-Peter Diettrich
    Replies:
    2
    Views:
    442
    Hans-Peter Diettrich
    Aug 22, 2008
  4. Brian

    Hello, Complex World

    Brian, Jan 12, 2010, in forum: C++
    Replies:
    5
    Views:
    404
    Brian
    Jan 15, 2010
  5. Larry
    Replies:
    27
    Views:
    452
    Michele Dondi
    Jan 25, 2005
Loading...

Share This Page