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

P

Pavel

mathog said:
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
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
 
P

Pavel

Noah said:
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 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
 
G

Guest

On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote:

[...] 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?

- 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.
 
J

Jorgen Grahn

.
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
 
J

Jorgen Grahn

On Friday, April 13, 2012 3:32:59 AM UTC+1, Pavel wrote: ....


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.

....
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.
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.

....
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 ...

/Jorgen
 
P

Pavel

Jorgen said:
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'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.



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.
...


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.

-Pavel
 
P

Pavel

Jorgen said:
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
 
M

Miles Bader

Pavel said:
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
 
P

Pavel

Miles said:
Pavel said:
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
 
T

Tobias Müller

Pavel said:
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
 
M

Miles Bader

Pavel said:
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
 
I

Ian Collins

Miles Bader said:
Pavel said:
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.

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.
 
G

Guest

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

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

probably a combination of 2 and 3! maybe it's my inner pedant but i though you said "of no technical merit"?
To me the best way to avoid the resentment is to really, honestly, try to
understand,

well I try...

<snip>
 
J

Jorgen Grahn

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


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


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.

/Jorgen
 
M

Miles Bader

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
 
M

Miles Bader

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?

-miles
 
M

Miles Bader

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
 
P

Pavel

Miles said:
Pavel said:
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.
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).

-Pavel
 
P

Pavel

Tobias said:
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?").

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Understanding Inheritance and Polymorphism 1
A real math problem. 5
Complex Python challenge 1 3
Code sharing 2
Hello, Complex World 5
Help with code 0
Real-world use of concurrent.futures 1
C programing code 6

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top