Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

180 views
Skip to first unread message

mathog

unread,
Apr 10, 2012, 11:54:39 AM4/10/12
to
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

K. Frank

unread,
Apr 10, 2012, 3:55:31 PM4/10/12
to
Hi David!

On Apr 10, 11:54 am, mathog <dmat...@gmail.com> 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

Ian Collins

unread,
Apr 10, 2012, 4:04:02 PM4/10/12
to
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

Jorgen Grahn

unread,
Apr 10, 2012, 6:26:48 PM4/10/12
to
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 .

Jeff-Relf.Me

unread,
Apr 10, 2012, 7:31:03 PM4/10/12
to
Re: "Methods for understanding complex, real world, C++"

Rewrite it.  That's what I do.

K. Frank

unread,
Apr 10, 2012, 8:37:51 PM4/10/12
to
Hello Jorgen!

On Apr 10, 6:26 pm, Jorgen Grahn <grahn+n...@snipabacken.se> 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

michael....@gmail.com

unread,
Apr 10, 2012, 8:29:58 PM4/10/12
to
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.

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 find out 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 for tools. 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.

nick_keigh...@hotmail.com

unread,
Apr 11, 2012, 4:20:53 AM4/11/12
to
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&#39;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.

Rui Maciel

unread,
Apr 11, 2012, 5:02:14 AM4/11/12
to
michael....@gmail.com 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

unread,
Apr 11, 2012, 5:06:19 AM4/11/12
to
nick_keigh...@hotmail.com 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

nick_keigh...@hotmail.com

unread,
Apr 11, 2012, 6:45:15 AM4/11/12
to rui.m...@gmail.com
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.

Jeff-Relf.Me

unread,
Apr 11, 2012, 11:52:27 AM4/11/12
to
Compared to thousands of lines of code
( 127 columns wide, densely packed ) houses are ⋅very⋅ simple.

It took me months to rewrite some IBM Fortran code to Windows 3.1 C;
but, once done, I had a "house" that I could live in for decades to come.

  I replaced a leaking pipe yesterday.
  Many years ago, when the semi⋅fexible copper pipe was installed,
  it was bent too much ( doubled over ) and condensation corroded it.

  Earlier, I added ( and replaced ) electrical outlets/switches, fans,
  light fixtures, vinyl flooring, sinks, sound⋅proofing, insulation,
  shower doors, shower heads, four E4200 routers ( cat5 ), toilets etc.

Uncommented, my code looks like this:

Cat( LnP B², int Sz² ) { if ( Sz² <= 0 ) return;
  LnP &B¹ = *Ln.PP, B¹⁺² ;  int Sz¹ = szStr( B¹ ), Sz¹⁺² = Sz¹ + Sz² ;
  if ( !Sz¹ || Sz¹⁺² > mxCols ) { Ln.PP -= !Sz¹ && Ln.PP > Ln.BB + iPP && ( Top⋅Most || *Ln.PP[-1] <= 32 );
    if ( Sz² < 4 || B²[2] != L'⌗' ) Sh( L"    %.*s", Sz², B² );
    else Sh( L"%.*s", Sz²-=2, B²+=2 );  return;  }

  B¹⁺² = MallocTmp( ++Sz¹⁺² * szChr ), Str( B¹⁺², L"%s%.*s", B¹, Sz², B² ), B¹ = B¹⁺² ;  }

Noah Roberts

unread,
Apr 11, 2012, 12:23:19 PM4/11/12
to
On Apr 10, 12:55 pm, "K. Frank" <kfrank2...@gmail.com> 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?

Jeff-Relf.Me

unread,
Apr 11, 2012, 2:22:06 PM4/11/12
to
Probably, there's too much source code to comment every little thing.
And, when you comment code, it might lead to "fixes",
possibly introducing new bugs.  Comments get stale, outdated.

If your outside coders want to merely ⋅extend⋅ to your code,
you could comment that section, nothing more.
They'd be writing extensions, like VBA "macros", Perl or JavaScript.

If these coders want to change everything ( to port it ? )
−− and if they're going to be around for years to come −−
they should take a few months to rewrite it, all of it.

Lynn McGuire

unread,
Apr 11, 2012, 3:35:34 PM4/11/12
to
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

Jorgen Grahn

unread,
Apr 11, 2012, 5:53:44 PM4/11/12
to
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 ...)

Joe keane

unread,
Apr 11, 2012, 6:36:41 PM4/11/12
to
In article <jm1l4g$a6e$1...@dont-email.me>, mathog <dma...@gmail.com> 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.

K. Frank

unread,
Apr 11, 2012, 7:06:27 PM4/11/12
to
Hi Noah!

On Apr 11, 12:23 pm, Noah Roberts <roberts.n...@gmail.com> wrote:
> On Apr 10, 12:55 pm, "K. Frank" <kfrank2...@gmail.com> 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

Noah Roberts

unread,
Apr 11, 2012, 7:05:08 PM4/11/12
to
On Apr 11, 3:36 pm, j...@panix.com (Joe keane) wrote:
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?

Robert Wessel

unread,
Apr 11, 2012, 8:37:39 PM4/11/12
to
Unfortunately the programs you'd be reshuffling would be too small by
a couple of orders of magnitude.

Miles Bader

unread,
Apr 12, 2012, 12:19:10 AM4/12/12
to
@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!

Christopher Pisz

unread,
Apr 12, 2012, 12:46:14 PM4/12/12
to
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.

mathog

unread,
Apr 12, 2012, 3:01:16 PM4/12/12
to
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

Pavel

unread,
Apr 12, 2012, 9:40:25 PM4/12/12
to
K. Frank wrote:
> Hello Jorgen!
>
> On Apr 10, 6:26 pm, Jorgen Grahn<grahn+n...@snipabacken.se> 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

Pavel

unread,
Apr 12, 2012, 9:48:16 PM4/12/12
to
To browse code Eclipse with CDT is pretty good if you can tame your projects for
it (it is usually possible, but for some of mine I still have to use the
immortal combination of gvim, ctags, fgrep and egrep).

Draw diagrams for your own understanding (I use Umbrello) but do not get too
crazy about it. Mostly no one will be looking at them except yourself.

Try to understand way of thinking of your predecessors and memorize stuff (I
know first hand how stupid it sounds and how painful it feels but somehow it
eventually pays off for me).

HTH
-Pavel

Pavel

unread,
Apr 12, 2012, 10:32:59 PM4/12/12
to
You may be in a trap that one of my friends called "write-only programming".
That is, the things you wrote may seem natural only to you -- because you know
what the code is supposed to do.

OO and event-driven stuff often have this property because they expose the
"wiring and glue" and hide the "meat" beyond them.

For example, 1000 "processEvent" functions each doing slighlty or completely
different thing may be much more difficult to understand than 1000 functions
having the actual names alluding on what the function does "in particular" (as
opposed to "process event" which is general). Of course, modifying the second
version of the code may require much more typing; but understanding could be as
much easier.

To summarize, there is often under-reported trade-off between the code's
flexibility and expandability and its readability.

To mitigate, try to limit your use of the nastiest for reading large codebases
(IMHO) C++ features:

- do not overload operators or write member operator functions (other than for
well-known *to others* idiomatic use, such as comparators for STL containers or
functors for STL algos)
- do not rely on namespaces to resolve name conflicts; at least not fully;
always get part of the namespace name into the class name (and maybe even some
function name).
- try to avoid function overloading as much as possible
- do not call your member functions anyhow similar to system function. That is,
avoid names like 'write'; instead be as specific as possible
'writeCrocodileIndexToXyzHeader()' (you can use underscores instead of camel if
you prefer; but the "line-of-code real estate" is at premium when you start
using really useful names so you might want to at least look into using camels).
- Do not use utility methods in the namespaces; instead use utility classes with
static function (to enforce the qualification of function name with the class
name).

The above might explain why I often favor C over C++ for bigger projects
(despite the C++ supposedly being better for them).

The following are not C++-specific

- use long readable names for variables (other than parameters of short
functions with self-explaining names)
- (I know, this will have lots of enemies) do not over-break your functions onto
smaller ones without significant and immediate gain (within reason, of course --
a function longer than a screen may be worth breaking down). It is easier to
follow one 50-line function with one-liner "section headers" in comments than 10
5-line functions calling each other and intermixed in alphabetical order even if
their names as so good that they "do not require comments").
- despite the previous point, do put functions in files in alphabetical order.
- and in general, only add an infrastructure facility if and when it is needed
and gives palpable and immediate gain. Do not add code "for future".
- Do not hesitate to remove "perfectly good" infrastructure code or glue as soon
as it is no longer used (even if you are 100% sure it is not used only
temporarily). To feel better about it, just think how much less you will have to
explain to your nasty manager or comment.

And the following is not even technical at all:

- Try to gain friends, not enemies, among your co-workers. Explain your ideas.
Take other people's ideas (sometimes do it even if you believe their ideas have
no technical merit) to get them involved. And sometimes you will avoid the trap
of your own biases against their ideas this way. As soon as they are on "write"
rather than "read" side of the fence, you have your allies. Make them invested
by letting them have a piece. Never get tired to explain (to me personally,
vis-a-vis and e-mails is a much better setting for getting ideas across than the
team meetings where a participant's goal is sometimes to look good rather than
to build understanding).

HTH
-Pavel

nick_keigh...@hotmail.com

unread,
Apr 13, 2012, 5:16:06 AM4/13/12
to
On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:

<snip>

> [...] there is often under-reported trade-off between the code's
> flexibility and expandability and its readability.
>
> To mitigate, try to limit your use of the nastiest for reading
> large codebases (IMHO) C++ features:
>
> - do not overload operators or write member operator functions (other
> than for well-known *to others* idiomatic use, such as comparators for STL
> containers or functors for STL algos)

and those following normal mathematical conventions. It seems natural to use operator+ for, say, vector addition

> - do not rely on namespaces to resolve name conflicts; at least not fully;
> always get part of the namespace name into the class name

not sure of the reasoning behind this.

> (and maybe even some function name).

*really* don't see this!

You'd write
queue.addToQueue (thingy);
rather than
queue.add (thingy);

more typing, less clarity!

> - try to avoid function overloading as much as possible

ok. I'm not a heavy user so no argument.

> - do not call your member functions anyhow similar to system function.

why not! Each class is effectivly a namespace. This is one of the things that makes C++ clearer than C. IMHO.

> That is,
> avoid names like 'write'; instead be as specific as possible
> 'writeCrocodileIndexToXyzHeader()'

no. really, no.
xyzHeader.write (crocodileIndex);
or
xyzHeader << crocodileIndex;

short and clear. Where comes this mania for War-and-Peace identifier names?

> [...] but the "line-of-code real estate" is at premium when you start
> using really useful names so you might want to at least look into using camels).

I don't accept that "long" is synonomous with "meaningful"

> - Do not use utility methods in the namespaces; instead use utility
> classes with static function (to enforce the qualification of function
> name with the class name).

you don't like namespaces so you reinvent namespaces

> The above might explain why I often favor C over C++ for bigger projects
> (despite the C++ supposedly being better for them).

it shows. You seem to be trying to make C++ look like C. I'm not sure why

> The following are not C++-specific
>
> - use long readable names for variables (other than parameters of short
> functions with self-explaining names)

up to a point.

> - (I know, this will have lots of enemies) do not over-break your functions onto
> smaller ones without significant and immediate gain (within reason, of course --
> a function longer than a screen may be worth breaking down). It is easier to
> follow one 50-line function with one-liner "section headers" in comments than 10
> 5-line functions calling each other

not sure this is always true.

> and intermixed in alphabetical order

yuk. This is a pain to maintain and not as helpful as some imagine. Your editor does have a search facility? Or are you still using coding pads?

> even if
> their names as so good that they "do not require comments").

you presumably don't agree this is possible?

<snip>

> - and in general, only add an infrastructure facility if and when it
> is needed and gives palpable and immediate gain. Do not add code
> "for future".

YAGNI it's called

> - Do not hesitate to remove "perfectly good" infrastructure code or
> glue as soon as it is no longer used (even if you are 100% sure it is
> not used only temporarily).

sounds like work creation

> To feel better about it, just think how much less you will have to
> explain to your nasty manager or comment.
>
> And the following is not even technical at all:
>
> - Try to gain friends, not enemies, among your co-workers. Explain your
> ideas.
> Take other people's ideas (sometimes do it even if you believe their
> ideas have no technical merit)

sorry I'm too Geek to even *think* this! I'd rather saw my own head off. Friends? Friends!? we're computer programmers we don't have no
stinking friends!

> to get them involved. And sometimes you will avoid the trap
> of your own biases against their ideas this way. As soon as they are on "write"
> rather than "read" side of the fence, you have your allies. Make them invested
> by letting them have a piece. Never get tired to explain (to me personally,
> vis-a-vis and e-mails is a much better setting for getting ideas across than the
> team meetings where a participant's goal is sometimes to look good rather than
> to build understanding).

90% of meetings are a complete waste of time and 90% of the time spent in the other meetings is also a wasted.

Jorgen Grahn

unread,
Apr 15, 2012, 5:56:25 AM4/15/12
to
On Fri, 2012-04-13, Pavel wrote:
...
> Draw diagrams for your own understanding (I use Umbrello) but do not get too
> crazy about it. Mostly no one will be looking at them except yourself.

I use pen and paper. I find that half the usefulness of that is
convincing yourself that you /can/ extract this information from the
code any time you want, in a few minutes.

Also, I find such diagrams are most useful if you don't aim for
completeness; i.e. you focus on a specific aspect of the code.
Automated tools on the other hand have no option but to include
/everything/.

Jorgen Grahn

unread,
Apr 15, 2012, 6:21:27 AM4/15/12
to
On Fri, 2012-04-13, nick_keigh...@hotmail.com wrote:
> On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:
...

>> - Do not use utility methods in the namespaces; instead use utility
>> classes with static function (to enforce the qualification of function
>> name with the class name).
>
> you don't like namespaces so you reinvent namespaces

I get the feeling he doesn't trust his coworkers not to nullify them
using "using", but ultimately only Pavel can motivate this choice of
his.

...
>> - (I know, this will have lots of enemies) do not over-break your functions onto
>> smaller ones without significant and immediate gain (within reason, of course --
>> a function longer than a screen may be worth breaking down). It is easier to
>> follow one 50-line function with one-liner "section headers" in comments than 10
>> 5-line functions calling each other
>
> not sure this is always true.

I've seen both versions, but the right one is usually a third: make
that long foo() function shorter by letting it work on a higher level
of abstraction. Create helper classes and helper functions; unify
error handling.

Just cutting foo() into foo_part1(), foo_part2() ... sucks, no doubt
about that even if you dream up semi-reasonable names for them.

If I had to choose, I'd prefer one long function.

>> and intermixed in alphabetical order
>
> yuk. This is a pain to maintain and not as helpful as some imagine. Your editor does have a search facility?
> Or are you still using coding pads?

I think he recommends /not to/ sort functions by name.

...
>> And the following is not even technical at all:
>>
>> - Try to gain friends, not enemies, among your co-workers. Explain your
>> ideas.
>> Take other people's ideas (sometimes do it even if you believe their
>> ideas have no technical merit)

> sorry I'm too Geek to even *think* this! I'd rather saw my own head
> off. Friends? Friends!? we're computer programmers we don't have no
> stinking friends!

Either there are no morons in your workplace, you're deluding
yourself, or you're in for a difficult time ...

I do what he describes. I wish I could also do it without
rensentment. Sometimes it's as if you've built a 1 mile bridge over a
ravine, and you know all too well that you were convinced to build one
foot in the middle out of spaghetti ...

Pavel

unread,
Apr 15, 2012, 7:33:44 PM4/15/12
to
Jorgen Grahn wrote:
> On Fri, 2012-04-13, nick_keigh...@hotmail.com wrote:
>> On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:
> ...
>
>>> - Do not use utility methods in the namespaces; instead use utility
>>> classes with static function (to enforce the qualification of function
>>> name with the class name).
>>
>> you don't like namespaces so you reinvent namespaces
>
> I get the feeling he doesn't trust his coworkers not to nullify them
> using "using", but ultimately only Pavel can motivate this choice of
> his.
It's not even that. The whole purpose of namespaces is to to use using on them
(whether declaration or directive) and avoid typing the namespace part of the
name in many cases (otherwise, why to use them at all and not to glue them to
the names?). This is great to avoid names conflict *for compiler*; but source
code is written (in the context of OP question at least, but by and large 90% of
the time) for human beings to read it. If a simple name in a namespace is used
in an unambiguous way *for compiler* it does not yet mean even the smartest
human being will be able to identify the correct namespace within reasonable
time and without shifting the focus of his/her attention.

>
> ...
>>> - (I know, this will have lots of enemies) do not over-break your functions onto
>>> smaller ones without significant and immediate gain (within reason, of course --
>>> a function longer than a screen may be worth breaking down). It is easier to
>>> follow one 50-line function with one-liner "section headers" in comments than 10
>>> 5-line functions calling each other
>>
>> not sure this is always true.
>
> I've seen both versions, but the right one is usually a third: make
> that long foo() function shorter by letting it work on a higher level
> of abstraction. Create helper classes and helper functions; unify
> error handling.
That's kinda a moot point: uniformity is great for the writer; often it is a
distractor for the reader though. To give your an example, if "process message"
function in a some foo-baz server is supposed to create a FooResponder and add
it to BarReactor then I would prefer something like:

void
FooBazServer::processMessage()
{
createFooResponderAndAddItToBarReactor();
}

and implementing in that createFooResponderAndAddItToBarReactor(); functions to
writing the code directly in FooBazServer::processMessage().

And the next logical step is of course to get rid of telling-me-nothing
FooBazServer::processMessage() (or operator() for that matter :-) ). Maybe I can
dispatch the control somehow differently directly to my
createFooResponderAndAddItToBarReactor() (via a table of member functions) and
avoid writing multiple functions with uniform names?

I am sorry if I misunderstood your idea about working on a higher level of
abstraction though.

>
> Just cutting foo() into foo_part1(), foo_part2() ... sucks, no doubt
> about that even if you dream up semi-reasonable names for them.
>
> If I had to choose, I'd prefer one long function.



>
>>> and intermixed in alphabetical order
>>
>> yuk. This is a pain to maintain and not as helpful as some imagine. Your editor does have a search facility?
>> Or are you still using coding pads?
>
> I think he recommends /not to/ sort functions by name.
Well, if you have many of them it is often the only reasonable way to then add
another one (unless you just throw new functions at the end or beginning in the
order they appear -- which is not necessarily over-bad; but motivates other
people to reorder them to their principles which will puzzle you if/when you are
back to your code. If you have "alphabetical" principle you can always ask them
to keep to the standard :-) ). But, if there are too many of them to do
something simple, it's worthy to try to reduce the number.. within reason, of
course.

>
> ...
>>> And the following is not even technical at all:
>>>
>>> - Try to gain friends, not enemies, among your co-workers. Explain your
>>> ideas.
>>> Take other people's ideas (sometimes do it even if you believe their
>>> ideas have no technical merit)
>
>> sorry I'm too Geek to even *think* this! I'd rather saw my own head
>> off. Friends? Friends!? we're computer programmers we don't have no
>> stinking friends!
>
> Either there are no morons in your workplace, you're deluding
> yourself, or you're in for a difficult time ...
>
> I do what he describes. I wish I could also do it without
> rensentment. Sometimes it's as if you've built a 1 mile bridge over a
> ravine, and you know all too well that you were convinced to build one
> foot in the middle out of spaghetti ...

To me the best way to avoid the resentment is to really, honestly, try to
understand, being even more ready to change my mind than is objectively
justified (in my biased opinion, of course). As I talk with a person with the
sincere desire to understand something that is on the first sight (or even in
fact) counter-intuitive or has no merit, trying to remove mutual preoccupations
(and for doing that, I have to admit to myself that I can be preoccupied and
even seem a moron to him/her), I can often create or strengthen the relationship
that makes it easier to find those notorious "win-win" solutions that do not
leave my geeky side dissatisfied. I am trying to think of these relationships as
the primary goal of these interactions and of the technical solutions as a
byproduct whose quality is necessarily heavily dependent on the quality of the
relationship.

I am first trying to find good points in the other person's position (even if it
is impossible to realize that merit the way they want it). Then it is sometimes
possible to take it out (of course giving full credit to the original author)
and integrate into a better solution. It is amazing to see how seemingly
intractable people become reasonable after you show them how their contribution
will improve the final solution. Then they might stop objecting to ditching the
rest of the stuff.

If in my final opinion the alternatives are just different ways of skinning same
cat, I tend to accept the other person's way. This gives me an additional
selfish advantage: they are more likely to "own" the resulting code at earnest
in the future and I can move on to some more fascinating stuff :-).

Of course, building these bridges when relationships are spoiled from the very
beginning is much more problematic and, even when possible, takes much greater
time, effort and patience.

>
> /Jorgen
>

-Pavel

Pavel

unread,
Apr 15, 2012, 7:43:14 PM4/15/12
to
Jorgen Grahn wrote:
> On Fri, 2012-04-13, Pavel wrote:
> ...
>> Draw diagrams for your own understanding (I use Umbrello) but do not get too
>> crazy about it. Mostly no one will be looking at them except yourself.
>
> I use pen and paper. I find that half the usefulness of that is
> convincing yourself that you /can/ extract this information from the
> code any time you want, in a few minutes.
>
> Also, I find such diagrams are most useful if you don't aim for
> completeness; i.e. you focus on a specific aspect of the code.
> Automated tools on the other hand have no option but to include
> /everything/.
>
> /Jorgen
>

I fully agree -- I stop at the lowest level of details that gives me just enough
understanding. I am terrible with organizing my hard copies though and Umbrello
lets me then grep for a class name etc (it saves models in plain XML (XMI))).

This ability to search is to me one of the main advantages of paper-less
bureaucracy in general (there are drawbacks, of course; and they say that
drawing with traditional tools, especially alternating hands, makes you smarter...)

-Pavel

Miles Bader

unread,
Apr 15, 2012, 8:59:47 PM4/15/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
>> I get the feeling he doesn't trust his coworkers not to nullify
>> them using "using", but ultimately only Pavel can motivate this
>> choice of his.
>
> It's not even that. The whole purpose of namespaces is to to use
> using on them (whether declaration or directive) and avoid typing
> the namespace part of the name in many cases (otherwise, why to use
> them at all and not to glue them to the names?).

That really isn't true.

Real namespaces are better than "glued on" adhoc namespaces because
they allow _either_ explicit references or implicit [with "using"]
references, and that choice is in the hands of the user [of the
namespace] where it belongs. The appropriate choice can differ, for
the same namespace, depending on the context of the use.

-Miles

--
Corporation, n. An ingenious device for obtaining individual profit without
individual responsibility.

Pavel

unread,
Apr 15, 2012, 9:32:29 PM4/15/12
to
Miles Bader wrote:
> Pavel<pauldont...@removeyourself.dontspam.yahoo> writes:
>>> I get the feeling he doesn't trust his coworkers not to nullify
>>> them using "using", but ultimately only Pavel can motivate this
>>> choice of his.
>>
>> It's not even that. The whole purpose of namespaces is to to use
>> using on them (whether declaration or directive) and avoid typing
>> the namespace part of the name in many cases (otherwise, why to use
>> them at all and not to glue them to the names?).
>
> That really isn't true.
>
> Real namespaces are better than "glued on" adhoc namespaces because
> they allow _either_ explicit references or implicit [with "using"]
> references, and that choice is in the hands of the user [of the
> namespace] where it belongs. The appropriate choice can differ, for
> the same namespace, depending on the context of the use.
>
> -Miles
>
Well, because "explicit" references are possible without namespaces, the only
feature they are adding seems to be allowing to use the "implicit" ones.

By mentioning of "write-only" code in my original answer I was trying to make a
point that "more choices" is not necessarily equivalent to "better".
Specifically, "more choices" provided by namespaces may be desirable for code
writer but be rather hurtful for reader.

-Pavel

Tobias Müller

unread,
Apr 16, 2012, 2:39:29 AM4/16/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> wrote:
> It's not even that. The whole purpose of namespaces is to to use using
> on them (whether declaration or directive) and avoid typing the
> namespace part of the name in many cases (otherwise, why to use them
> at all and not to glue them to the names?).

What's really useful about namespaces is that you don't have to use
qualified names _inside_ the _same_ namespace. Most classes that I use are
actually defined in the current namespace, and I like to explicitely
qualify all others.

Tobi

Miles Bader

unread,
Apr 16, 2012, 8:32:40 PM4/16/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
>> Real namespaces are better than "glued on" adhoc namespaces because
>> they allow _either_ explicit references or implicit [with "using"]
>> references, and that choice is in the hands of the user [of the
>> namespace] where it belongs. The appropriate choice can differ,
>> for the same namespace, depending on the context of the use.
>
> Well, because "explicit" references are possible without namespaces,
> the only feature they are adding seems to be allowing to use the
> "implicit" ones.

That doesn't mean one always has to use that feature. However the
_ability_ to use that feature is important.

> By mentioning of "write-only" code in my original answer I was trying
> to make a point that "more choices" is not necessarily equivalent to
> "better". Specifically, "more choices" provided by namespaces may be
> desirable for code writer but be rather hurtful for reader.

"More explicit" names are not always "more readable," and can often be
_less_ readable, because the constant repetition obscures what's
actually meaningful.

A reasonable use of namespaces makes things explicit when that's the
most readable, and makes things implicit when _that's_ the most
readable.

Glued-on adhoc "namespaces" do not give you that choice, and so in the
end can result in less readable code.

-miles

--
Bore, n. A person who talks when you wish him to listen.

Scott Lurndal

unread,
Apr 16, 2012, 10:06:57 PM4/16/12
to
Miles Bader <mi...@gnu.org> writes:
>Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
>>> Real namespaces are better than "glued on" adhoc namespaces because
>>> they allow _either_ explicit references or implicit [with "using"]
>>> references, and that choice is in the hands of the user [of the
>>> namespace] where it belongs. The appropriate choice can differ,
>>> for the same namespace, depending on the context of the use.
>>
>> Well, because "explicit" references are possible without namespaces,
>> the only feature they are adding seems to be allowing to use the
>> "implicit" ones.
>
>That doesn't mean one always has to use that feature. However the
>_ability_ to use that feature is important.
>
>> By mentioning of "write-only" code in my original answer I was trying
>> to make a point that "more choices" is not necessarily equivalent to
>> "better". Specifically, "more choices" provided by namespaces may be
>> desirable for code writer but be rather hurtful for reader.
>
>"More explicit" names are not always "more readable," and can often be
>_less_ readable, because the constant repetition obscures what's
>actually meaningful.

I'd disagree with this. Without namespaces, an unqualified variable
is scoped local to the member function or is a class member (static
or not). It may be a global static if the coding guidelines allow such
a thing (good ones don't). By explicitly qualifying any other identifier,
one is instantly aware of where it is stored and/or defined. Using
namespaces (no pun intended) obscures that and makes understanding the
code more difficult.

None of the C++ projects that I've worked on (two operating systems,
a hypervisor, two full system simulators and a major CA's certificate
generation code) used namespaces, nor did most of them allow any
unqualified statics, which are almost always problematic in threaded
or re-entrant code. Of course, all of the above must be thread-safe
and re-entrant for proper operation.

scott

Miles Bader

unread,
Apr 16, 2012, 10:35:47 PM4/16/12
to
sc...@slp53.sl.home (Scott Lurndal) writes:
>> "More explicit" names are not always "more readable," and can often
>> be _less_ readable, because the constant repetition obscures what's
>> actually meaningful.
>
> I'd disagree with this.

Fair enough -- but it's certainly a debatable point, and I feel
confident to say there isn't any consensus.

-miles

--
`Suppose Korea goes to the World Cup final against Japan and wins,' Moon said.
`All the past could be forgiven.' [NYT]

Ian Collins

unread,
Apr 17, 2012, 12:06:07 AM4/17/12
to
Not really, consider code with lots of io. Does us look clearer with
"std::cin" and friends or with a using directive and "cin"?

Provided your naming conventions differ for namespaces and types (all
those I've used do), differentiating between a static class member and a
namespace scoped variable is straightforward.

> None of the C++ projects that I've worked on (two operating systems,
> a hypervisor, two full system simulators and a major CA's certificate
> generation code) used namespaces, nor did most of them allow any
> unqualified statics, which are almost always problematic in threaded
> or re-entrant code. Of course, all of the above must be thread-safe
> and re-entrant for proper operation.

Where these recent projects? It took a while for namespaces to be
widely used after they were introduced in the '98 standard. A
surprising number of libraries still have namespaces hidden in macros in
order to support legacy compilers.

--
Ian Collins

nick_keigh...@hotmail.com

unread,
Apr 17, 2012, 6:50:21 AM4/17/12
to
On Monday, April 16, 2012 12:33:44 AM UTC+1, Pavel wrote:
> Jorgen Grahn wrote:
> > On Fri, 2012-04-13, nick_keigh...@hotmail.com wrote:
> >> On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:

<snip>

> >>> the following is not even technical at all:
> >>>
> >>> - Try to gain friends, not enemies, among your co-workers. Explain your
> >>> ideas.
> >>> Take other people's ideas

I'll do that. And for the sake of quiet life I may use something that I think could be better. but...

> >>> (sometimes do it even if you believe their
> >>> ideas have no technical merit)

...I simply couldn't do this. How could you put something in your code that had /no/ technical merit!

> >> sorry I'm too Geek to even *think* this! I'd rather saw my own head
> >> off. Friends? Friends!? we're computer programmers we don't have no
> >> stinking friends!
> >
> > Either there are no morons in your workplace, you're deluding
> > yourself, or you're in for a difficult time ...

probably a combination of 2 and 3! maybe it's my inner pedant but i though you said "of no technical merit"?

> > I do what he describes. I wish I could also do it without
> > rensentment. Sometimes it's as if you've built a 1 mile bridge over a
> > ravine, and you know all too well that you were convinced to build one
> > foot in the middle out of spaghetti ...
>
> To me the best way to avoid the resentment is to really, honestly, try to
> understand,

well I try...

<snip>

Jorgen Grahn

unread,
Apr 17, 2012, 8:01:30 AM4/17/12
to
On Tue, 2012-04-17, nick_keigh...@hotmail.com wrote:
> On Monday, April 16, 2012 12:33:44 AM UTC+1, Pavel wrote:
>> Jorgen Grahn wrote:
>> > On Fri, 2012-04-13, nick_keigh...@hotmail.com wrote:
>> >> On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:
>
> <snip>
>
>> >>> the following is not even technical at all:
>> >>>
>> >>> - Try to gain friends, not enemies, among your co-workers. Explain your
>> >>> ideas.
>> >>> Take other people's ideas
>
> I'll do that. And for the sake of quiet life I may use something that I think could be better. but...
>
>> >>> (sometimes do it even if you believe their
>> >>> ideas have no technical merit)
>
> ...I simply couldn't do this. How could you put something in your code
> that had /no/ technical merit!
>
>> >> sorry I'm too Geek to even *think* this! I'd rather saw my own head
>> >> off. Friends? Friends!? we're computer programmers we don't have no
>> >> stinking friends!
>> >
>> > Either there are no morons in your workplace, you're deluding
>> > yourself, or you're in for a difficult time ...
>
> probably a combination of 2 and 3! maybe it's my inner pedant but i though
> you said "of no technical merit"?

To be precise, *Pavel* said that. But I think I read it less
strictly than you.

Scott Lurndal

unread,
Apr 17, 2012, 11:24:09 AM4/17/12
to
>"std::cin" and friends or with a using directive and "cin"?'

I will admit that none of the projects I referred to below used C++
I/O. Nor did any of them use STL (for performance reasons), even tho
STL was created by one of my employers.

>
>Provided your naming conventions differ for namespaces and types (all
>those I've used do), differentiating between a static class member and a
>namespace scoped variable is straightforward.
>
>> None of the C++ projects that I've worked on (two operating systems,
>> a hypervisor, two full system simulators and a major CA's certificate
>> generation code) used namespaces, nor did most of them allow any
>> unqualified statics, which are almost always problematic in threaded
>> or re-entrant code. Of course, all of the above must be thread-safe
>> and re-entrant for proper operation.
>
>Where these recent projects? It took a while for namespaces to be
>widely used after they were introduced in the '98 standard.

About half before, the other half after. However, since none of them
used STL (see above), namespaces weren't that useful.

scott

Miles Bader

unread,
Apr 17, 2012, 3:50:11 PM4/17/12
to
sc...@slp53.sl.home (Scott Lurndal) writes:
>>Where these recent projects? It took a while for namespaces to be
>>widely used after they were introduced in the '98 standard.
>
> About half before, the other half after. However, since none of them
> used STL (see above), namespaces weren't that useful.

What do namespaces have to do with the STL...?

-miles

--
Brain, n. An apparatus with which we think we think.

Scott Lurndal

unread,
Apr 17, 2012, 4:18:40 PM4/17/12
to
Miles Bader <mi...@gnu.org> writes:
>sc...@slp53.sl.home (Scott Lurndal) writes:
>>>Where these recent projects? It took a while for namespaces to be
>>>widely used after they were introduced in the '98 standard.
>>
>> About half before, the other half after. However, since none of them
>> used STL (see above), namespaces weren't that useful.
>
>What do namespaces have to do with the STL...?
>

Ok. I used STL here to refer to the standard C++ library which
includes std:: namespace et alia. My bad. We used none of that.

scott

Miles Bader

unread,
Apr 17, 2012, 9:31:04 PM4/17/12
to
Er, but anyway, my question was: Why does not using the STL make
namespaces any less useful?

-miles

--
Cannon, n. An instrument employed in the rectification of national boundaries.

Scott Lurndal

unread,
Apr 17, 2012, 9:36:05 PM4/17/12
to
Miles Bader <mi...@gnu.org> writes:
>sc...@slp53.sl.home (Scott Lurndal) writes:
>>>>>Where these recent projects? It took a while for namespaces to be
>>>>>widely used after they were introduced in the '98 standard.
>>>>
>>>> About half before, the other half after. However, since none of them
>>>> used STL (see above), namespaces weren't that useful.
>>>
>>>What do namespaces have to do with the STL...?
>>
>> Ok. I used STL here to refer to the standard C++ library which
>> includes std:: namespace et alia. My bad. We used none of that.
>
>Er, but anyway, my question was: Why does not using the STL make
>namespaces any less useful?

Because everything in our code was part of one of our classes. Either static
data/function members or regular members. All of which are impliciltly or
explicitly qualified by the class name. There was no need for namespaces.

scott

Miles Bader

unread,
Apr 17, 2012, 10:00:26 PM4/17/12
to
sc...@slp53.sl.home (Scott Lurndal) writes:
>>Er, but anyway, my question was: Why does not using the STL make
>>namespaces any less useful?
>
> Because everything in our code was part of one of our classes. Either static
> data/function members or regular members. All of which are impliciltly or
> explicitly qualified by the class name. There was no need for namespaces.

Er, OK, but then of course your classes themselves are in the global
namespace.

You might consider that OK, but many would consider it a good use of
namespaces to collect all those classes in a library / module /
whatever namespace (maybe with some sub-namespaces as well).

... and of course, either way, there seems to be no connection with
whether one uses STL / std:: or not...

-miles

--
=====
(^o^;
(()))
*This is the cute octopus virus, please copy it into your sig so it can spread.

Pavel

unread,
Apr 18, 2012, 10:09:14 PM4/18/12
to
Not quite true. Nobody prevents you from using small names locally if you
overuse your "big names". E.g. implementing delegating long public names to
shorter static,
anonymous-namespace-scoped or protected names.

For other classes/modules -- yes, I prefer to force using longer names. And this
is because "you" is not really "you" but someone else whose choice of names is
outside your control -- and this is true for any sizable project.

Many people forget that the programming is not talking to oneself or one's
compiler or computer but collaboration with other people who can be expected to
sometimes act unwisely (from one's point of view).

As an example of good naming: Windows or X API names may be annoyingly long but
certainly unambiguous (which is to me the best kind of "expressive") and do not
tempt people to overload them (I mean, they are C, so they cannot really be
overload but even if they were C++ I don't think people would rush to overload
such calls).

> -miles
>

-Pavel

Pavel

unread,
Apr 18, 2012, 10:25:53 PM4/18/12
to
Yes, but this works with utility classes as well. Of course, namespaces are more
convenient in that they are open..

At the same time, openness they creates an uncertainty ("is this all stuff I
need to know about XYZ or there is something else in another source file?").

Note I am not against using namespaces, what I say exactly is:
a. There is no free cheese; more opportunities mean more possibilities for abuse
(and from Murphy laws we know all of them will be exploited).
b. For classes, I often prefer to prefix names within namespace with some *part*
(or abbreviation) of namespace name.
c. For standalone functions, I (almost always) prefer using utility classes to
namespaces. This is because, whereas non-static member function call site may
give some idea of its class (maybe the object is defined locally or for a change
has a good name), standalone function's call site does not carry any info of its
enclosing scope (if it is a namespace).

-Pavel

Miles Bader

unread,
Apr 18, 2012, 10:41:20 PM4/18/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
>> Glued-on adhoc "namespaces" do not give you that choice, and so in the
>> end can result in less readable code.
>
> Not quite true. Nobody prevents you from using small names locally if
> you overuse your "big names". E.g. implementing delegating long public
> names to shorter static, anonymous-namespace-scoped or protected
> names.

Er, how? The only ways I can think of are very annoying, requiring one
to explicitly add a definition for _every name_.

> For other classes/modules -- yes, I prefer to force using longer
> names. And this is because "you" is not really "you" but someone else
> whose choice of names is outside your control -- and this is true for
> any sizable project.
>
> Many people forget that the programming is not talking to oneself or
> one's compiler or computer but collaboration with other people who can
> be expected to sometimes act unwisely (from one's point of view).

Yes, we know that. Please don't be condescending.

Excessive use of names with long redundant prefixes can be obfuscating,
making code _less_ readable. You can disagree with that, of course,
but that's more or less the point: there is no consensus among on this
issue among reasonable people.

-miles

--
`To alcohol! The cause of, and solution to,
all of life's problems' --Homer J. Simpson

Pavel

unread,
Apr 18, 2012, 11:04:56 PM4/18/12
to
Miles Bader wrote:
> Pavel<pauldont...@removeyourself.dontspam.yahoo> writes:
>>> Glued-on adhoc "namespaces" do not give you that choice, and so in the
>>> end can result in less readable code.
>>
>> Not quite true. Nobody prevents you from using small names locally if
>> you overuse your "big names". E.g. implementing delegating long public
>> names to shorter static, anonymous-namespace-scoped or protected
>> names.
>
> Er, how? The only ways I can think of are very annoying,
Below you asked me not to be condescending and I apologize in advance. but this
is exactly the point: you are talking about annoyance *for the writer* and do
not seem to care of a reader. The reader (of the code using long name or of the
in-scope code using short name) will not find reading names that are making
sense annoying. What s/he will find annoying is reading stumbling blocks when a
short "expressive" name like "write" or, even worse '+', makes him/her jump via
hundreds of definitions of "write" or 'operator*" (at extreme, mentally
instantiating templates and applying conversion rules) to understand what this
"write" means at this particular call site instead of just reading
writeBlueCrocodileToGreenSwamp() or mul_tri_block_matrices_strassen() and
immediately knowing what's going on (I made up ugly names on purpose; IMHO they
are infinitely better than sleeky-and-meaningless "write" or "*" as they are).

requiring one
> to explicitly add a definition for _every name_.
That's what I meant:

void
LongLongLongLongLongExternOrPublicName(...)
{
ShortStaticOrAnonNamespaceOrProtectedNameForUseInSameFileOrClassScope(...);
// admittedly, not too short here :-)
}

I am not sure whether or not this is what you called "annoying".

>
>> For other classes/modules -- yes, I prefer to force using longer
>> names. And this is because "you" is not really "you" but someone else
>> whose choice of names is outside your control -- and this is true for
>> any sizable project.
>>
>> Many people forget that the programming is not talking to oneself or
>> one's compiler or computer but collaboration with other people who can
>> be expected to sometimes act unwisely (from one's point of view).
>
> Yes, we know that. Please don't be condescending.
>
> Excessive use of names with long redundant prefixes can be obfuscating,
> making code _less_ readable. You can disagree with that, of course,
> but that's more or less the point: there is no consensus among on this
> issue among reasonable people.
>
> -miles
>

-Pavel

Ian Collins

unread,
Apr 18, 2012, 11:56:18 PM4/18/12
to
On 04/19/12 02:09 PM, Pavel wrote:
>
> As an example of good naming: Windows or X API names may be annoyingly long but
> certainly unambiguous (which is to me the best kind of "expressive") and do not
> tempt people to overload them (I mean, they are C, so they cannot really be
> overload but even if they were C++ I don't think people would rush to overload
> such calls).

The X API uses the shortest possible prefix: X. At least 2 characters
shorter than any qualified namespace name..

The function names are also as concise as reasonably possible, Certainly
not "annoyingly long".

--
Ian Collins

Miles Bader

unread,
Apr 19, 2012, 12:33:25 AM4/19/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
> Below you asked me not to be condescending and I apologize in
> advance. but this is exactly the point: you are talking about
> annoyance *for the writer* and do not seem to care of a reader.

No. I'm talking about both. [Which should be pretty obvious, as I
keep saying it explicitly...]

-miles

--
Alone, adj. In bad company.

Jorgen Grahn

unread,
Apr 19, 2012, 9:58:50 AM4/19/12
to
On Thu, 2012-04-19, Pavel wrote:
> Tobias Müller wrote:
>> Pavel<pauldont...@removeyourself.dontspam.yahoo> wrote:
>>> It's not even that. The whole purpose of namespaces is to to use using
>>> on them (whether declaration or directive) and avoid typing the
>>> namespace part of the name in many cases (otherwise, why to use them
>>> at all and not to glue them to the names?).
>>
>> What's really useful about namespaces is that you don't have to use
>> qualified names _inside_ the _same_ namespace. Most classes that I use are
>> actually defined in the current namespace, and I like to explicitely
>> qualify all others.
>>
>> Tobi
> Yes, but this works with utility classes as well. Of course, namespaces are more
> convenient in that they are open..
>
> At the same time, openness they creates an uncertainty ("is this all stuff I
> need to know about XYZ or there is something else in another source file?").

IMO it's a fake uncertainty, because you don't need to know
*everything* about a namespace to use some of it. (If you *do*, maybe
it should have been a class, but you usually don't need to know
everything about large classes, either.)

> Note I am not against using namespaces, what I say exactly is:
> a. There is no free cheese; more opportunities mean more possibilities for abuse
> (and from Murphy laws we know all of them will be exploited).
> b. For classes, I often prefer to prefix names within namespace with some *part*
> (or abbreviation) of namespace name.
> c. For standalone functions, I (almost always) prefer using utility classes to
> namespaces. This is because, whereas non-static member function call site may
> give some idea of its class (maybe the object is defined locally or for a change
> has a good name), standalone function's call site does not carry any info of its
> enclosing scope (if it is a namespace).

Maybe I'm missing something, but doesn't the line

foo:sort(a, b);

say that sort() comes from namespace 'foo'? Or is it using sort()
from *within* foo that worries you?

Dombo

unread,
Apr 19, 2012, 5:20:29 PM4/19/12
to
Op 19-Apr-12 4:25, Pavel schreef:
> Tobias Müller wrote:
>> Pavel<pauldont...@removeyourself.dontspam.yahoo> wrote:
>>> It's not even that. The whole purpose of namespaces is to to use using
>>> on them (whether declaration or directive) and avoid typing the
>>> namespace part of the name in many cases (otherwise, why to use them
>>> at all and not to glue them to the names?).
>>
>> What's really useful about namespaces is that you don't have to use
>> qualified names _inside_ the _same_ namespace. Most classes that I use
>> are
>> actually defined in the current namespace, and I like to explicitely
>> qualify all others.
>>
>> Tobi
> Yes, but this works with utility classes as well. Of course, namespaces
> are more convenient in that they are open..
>
> At the same time, openness they creates an uncertainty ("is this all
> stuff I need to know about XYZ or there is something else in another
> source file?").

These days many editors will tell you what is in the namespace after you
entered its name. Anyway why do you need to know everything that is in a
namespace?

> Note I am not against using namespaces, what I say exactly is:
> a. There is no free cheese; more opportunities mean more possibilities
> for abuse (and from Murphy laws we know all of them will be exploited).

True, more isn't necessarily better. But that doesn't mean that any
feature that can be abused should be avoided. If one leaves out every
feature that can be abused, one is left with a very small programming
language.

Especially with C++ language features should be used judiciously. That
is not to say they should not be used at all.

> b. For classes, I often prefer to prefix names within namespace with
> some *part* (or abbreviation) of namespace name.

This creates the same "uncertainty" you mentioned above (though a decent
editor solves this problem as well).

> c. For standalone functions, I (almost always) prefer using utility
> classes to namespaces. This is because, whereas non-static member
> function call site may give some idea of its class (maybe the object is
> defined locally or for a change has a good name), standalone function's
> call site does not carry any info of its enclosing scope (if it is a
> namespace).

You may have point here, but frankly I'm not sure what the point is you
are trying to make. Do you mean that if you use a static member function
in a class you are forced to always specify its scope, whereas a
standalone function in a namespace you can get by with just specifying
the name of function if you are in calling it from the same namespace or
have somewhere a 'using namespace' directive in the compilation unit? In
that case I somewhat agree. Not enough to avoid namespaces altogether,
but I'm reluctant to use the 'using namespace' directive to avoid nasty
surprises.





Pavel

unread,
Apr 19, 2012, 10:54:54 PM4/19/12
to
Ian Collins wrote:
> On 04/19/12 02:09 PM, Pavel wrote:
>>
>> As an example of good naming: Windows or X API names may be annoyingly long but
>> certainly unambiguous (which is to me the best kind of "expressive") and do not
>> tempt people to overload them (I mean, they are C, so they cannot really be
>> overload but even if they were C++ I don't think people would rush to overload
>> such calls).
>
> The X API uses the shortest possible prefix: X. At least 2 characters shorter
> than any qualified namespace name..
Isn't that exactly what I suggest? Quoting my advice that IMHO spurred the
discussion:

"always get *part of* the namespace name into the class name"

>
> The function names are also as concise as reasonably possible,
Sometimes they are and sometimes not. Why XSetCloseDownMode() cannot be simply
XSetCloseMode() is not quite clear to me. Is there close up mode in X?

> Certainly not "annoyingly long".
Actually, I agree -- I personally am fine with them (even with that CloseDown)
as should be clear from my post. I was simply relating to Miles Bider's point
"because the constant repetition obscures what's actually meaningful" --
"annoying" seems to be a fair summary of this quote, doesn't it?

-Pavel

Pavel

unread,
Apr 19, 2012, 11:39:38 PM4/19/12
to
Jorgen Grahn wrote:
> On Thu, 2012-04-19, Pavel wrote:
>> Tobias Müller wrote:
>>> Pavel<pauldont...@removeyourself.dontspam.yahoo> wrote:
>>>> It's not even that. The whole purpose of namespaces is to to use using
>>>> on them (whether declaration or directive) and avoid typing the
>>>> namespace part of the name in many cases (otherwise, why to use them
>>>> at all and not to glue them to the names?).
>>>
>>> What's really useful about namespaces is that you don't have to use
>>> qualified names _inside_ the _same_ namespace. Most classes that I use are
>>> actually defined in the current namespace, and I like to explicitely
>>> qualify all others.
>>>
>>> Tobi
>> Yes, but this works with utility classes as well. Of course, namespaces are more
>> convenient in that they are open..
>>
>> At the same time, openness they creates an uncertainty ("is this all stuff I
>> need to know about XYZ or there is something else in another source file?").
>
> IMO it's a fake uncertainty, because you don't need to know
> *everything* about a namespace to use some of it. (If you *do*, maybe
> it should have been a class, but you usually don't need to know
> everything about large classes, either.)
Well, one of the principles of good OO design is to keep class's behaviors
"highly cohesive". Something like "one class -- one concept with consistent set
of highly cohesive behaviors". Cohesive behaviors beg for completeness (say, if
you see function declarations to add to container but not remove from it, you
will likely see something is missing and start searching for where it is).

Now, with the namespace, if we decide cohesion is not a goal, the only goal left
seems to be (correct me if I am wrong) to use short tell-me-nothing names
without confusing *compiler* (which is the last guy to be concerned with IMHO).

On the other hand, if cohesion *is* a goal in designing a namespace,
completeness should be, too, and the above-mentioned uncertainty should be a
fair concern.

This is not to say namespaces are always bad.
>
>> Note I am not against using namespaces, what I say exactly is:
>> a. There is no free cheese; more opportunities mean more possibilities for abuse
>> (and from Murphy laws we know all of them will be exploited).
>> b. For classes, I often prefer to prefix names within namespace with some *part*
>> (or abbreviation) of namespace name.
>> c. For standalone functions, I (almost always) prefer using utility classes to
>> namespaces. This is because, whereas non-static member function call site may
>> give some idea of its class (maybe the object is defined locally or for a change
>> has a good name), standalone function's call site does not carry any info of its
>> enclosing scope (if it is a namespace).
>
> Maybe I'm missing something, but doesn't the line
>
> foo:sort(a, b);
>
> say that sort() comes from namespace 'foo'? Or is it using sort()
> from *within* foo that worries you?
This may be of minor concern. The main concern is other usage, namely using
directive and declaration, which allow using sort() from outside (although
sort() is not too bad; 'get()', 'send()' or 'notify()' would be much more
interesting (unless it's ::send() :-) ). Not to mention operator+ which is even
worse than add() which is bad enough as it is).

Both usages you exemplify (foo::sort(a, b) externally and sort(a,b) within foo)
are not specific to namespaces; you could easily do same with foo being a
utility class.

On a side note, I do not think I am getting across my point that I am not
against namespaces but few their specific [ab]uses that proliferate short
telling-me-nothing names.

>
> /Jorgen
>

-Pavel

Pavel

unread,
Apr 19, 2012, 11:54:25 PM4/19/12
to
The "uncertainty" I mentioned above had nothing to do with prefixing names; it
was related to the fact that namespaces, as opposed to classes, are open (that
is, more declarations can be added to a namespace in a different compilation unit).

This kind of uncertainty aside, I cannot understand how adding a prefix to a
name can create any uncertainty whatsoever

(though a decent editor
> solves this problem as well).
>
>> c. For standalone functions, I (almost always) prefer using utility
>> classes to namespaces. This is because, whereas non-static member
>> function call site may give some idea of its class (maybe the object is
>> defined locally or for a change has a good name), standalone function's
>> call site does not carry any info of its enclosing scope (if it is a
>> namespace).
>
> You may have point here, but frankly I'm not sure what the point is you are
> trying to make. Do you mean that if you use a static member function in a class
> you are forced to always specify its scope, whereas a standalone function in a
> namespace you can get by with just specifying the name of function if you are in
> calling it from the same namespace or have somewhere a 'using namespace'
> directive in the compilation unit? In that case I somewhat agree.
Yes
Not enough to
> avoid namespaces altogether,
Avoiding namespaces altogether is not something I advocate; I simply gave my
advices on readability that included avoiding what I feel is abusing namespaces.
but I'm reluctant to use the 'using namespace'
> directive to avoid nasty surprises.
I use it sometimes, to include my company's namespaces where names are built in
accordance with the above rules. The code is generally readable then; sometimes
an unqualified prefixed name is puzzling; but it is almost never ambiguous or
misleading; and the prefix at very least gives a good clue what namespace it may
be in.

I generally do not use it to include external or Standard C++ library namespaces
(sometimes I use "using namespace std;" for brevity in short examples, probing
snippets or in this group but I am getting rid of these if I am to productionize
the code).

-Pavel

Miles Bader

unread,
Apr 20, 2012, 1:31:18 AM4/20/12
to
Pavel <pauldont...@removeyourself.dontspam.yahoo> writes:
>> Certainly not "annoyingly long".
>
> Actually, I agree -- I personally am fine with them (even with that
> CloseDown) as should be clear from my post. I was simply relating to
> Miles Bader's point "because the constant repetition obscures what's
> actually meaningful" --
> "annoying" seems to be a fair summary of this quote, doesn't it?

But X, with its short-n-sweet prefix is both an exception (obviously
not every package can use a single-letter name, and meaningful names
tend to be much olonger), and illustration of another problem with
hard-wired prefixes:

Because they're attached to _everything_ software authors often try to
pick the shortest possible prefix they think they can get away with,
which can result in both some awkward naming (your package is called
"ThreadExplorer", and has a module called "Manager", but you use a
prefix of "threxmgr" -- not _that_ bad, but you can see how things can
get shaky), and skipping some naming altogether (i.e., everything just
gets shoved into the top-level "namespace").

-miles

--
Dinanzi a me non fuor cose create
se non etterne, e io etterno duro.
Lasciate ogne speranza, voi ch'intrate.

Jorgen Grahn

unread,
Apr 22, 2012, 12:37:28 PM4/22/12
to
I hope you are wrong, because that is of course a ridiculous goal.

My goal with namespaces is roughly this: if I am tempted to add a
prefix to a set of class and function names, templates, constants and
so on, I put them in a namespace instead. And this is when they seem
to form a subsystem in some way; when I already think of them as
related, I might as well make that explicit in the code.

I typically don't use "using" etc much -- I spell out the namespace name.
Not having to use it *within* the namespace is a big enough benefit.

[snip]

> On a side note, I do not think I am getting across my point that I am not
> against namespaces but few their specific [ab]uses that proliferate short
> telling-me-nothing names.

True. It seems to me there's not much use for them when you've
removed the part you see as abuse.
0 new messages