Using namespaces to partition code

14 views
Skip to first unread message

Scott Meyers

unread,
Feb 13, 2004, 6:17:32 AM2/13/04
to
Suppose I have some classes and functions that can be partitioned into
those that do and do not satisfy some criterion. For example, some are
"certified" and some are not. Some are thread-safe and some are not. Some
are portable and some are not. Let's call the code that satisfies the
criterion the green code and the code that doesn't satisfy it the red code.

To preserve the "greenness" property, green code must call only green code.
Red code can do whatever it wants. (Green code is a lot like being const,
while red code is a lot like being non-const: const code can call only
const code, but non-const code can call anything it wants to.)

I'd like to have a way to (1) prevent people from accidently modifying
green code to call red code and (2) to easily find places where a conscious
decision has been made have green code call red code. The idea I came up
with was to use namespaces for this. Green code goes in the green
namespace. Red code goes in the red namespace, but it uses a using
directive to haul the green namespace in, too:

namespace green {
void greenFunc();
}

namespace red {
using namespace green;
void redFunc();
}

Setting aside Koenig lookup, the idea is that code in the green namespace
can't call into code in the red namespace without explicit qualification:

void green::greenFunc()
{
redFunc(); // error!
red::redFunc(); // okay
}

Red code is less encumbered:

void red::redFunc()
{
greenFunc(); // okay
}

Koenig lookup complicates matters, but at this point I'm curious about two
things.

1. Does this seem like a reasonable approach to this problem, or is
there a better way to solve it?

2. I'd call this an "application" of namespaces, i.e., a use of
namespaces to solve a problem other than that of preventing name
clashes. (The goal here isn't to prevent name clashes, it's to
partition a body of code into parts that do and don't satisfy some
criterion.) What other "applications" of namespaces are there?

Thanks for any insights,

Scott

PS - As an aside, when I compile the code above with the current VC, I get
these warnings:

d:\temp\foo.cpp(34): warning C4717:
'green::greenFunc': recursive on all control paths,
function will cause runtime stack overflow
d:\temp\foo.cpp(38): warning C4718:
'green::greenFunc': recursive call has no side effects, deleting

Call me easily amused, but I think that's cool!

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Rob Mayoff

unread,
Feb 13, 2004, 7:38:42 PM2/13/04
to
Scott Meyers <Use...@aristeia.com> wrote in message news:<MPG.1a95b9e49...@news.hevanet.com>...

> To preserve the "greenness" property, green code must call only green code.
> Red code can do whatever it wants. (Green code is a lot like being const,
> while red code is a lot like being non-const: const code can call only
> const code, but non-const code can call anything it wants to.)

If a green function has a function pointer parameter, is a red
function allowed to call the green function, passing in a pointer to a
red function?

Kevin Cline

unread,
Feb 14, 2004, 7:26:58 AM2/14/04
to
Scott Meyers <Use...@aristeia.com> wrote in message news:<MPG.1a95b9e49...@news.hevanet.com>...

An interesting idea. I like it because your approach makes
potentially bad code easy to spot. However, I typically like to keep
dependencies between namespaces acyclic, and since some green code has
to call some red code, and some red code has to call some green code,
I would end up creating lower-level namespaces to keep the
dependencies straight, so that green::top dependend on red::middle,
which depended on green::low.

Alternatively, you could add prefixes or suffixes to namespaces
containing red code:

namespace middle_tu_eu_uc { // thread-unsafe, exception_unsafe,
uncertified

Scott Meyers

unread,
Feb 14, 2004, 9:22:45 AM2/14/04
to
On 13 Feb 2004 19:38:42 -0500, Rob Mayoff wrote:
> If a green function has a function pointer parameter, is a red
> function allowed to call the green function, passing in a pointer to a
> red function?

My (sketchy) thinking on this is that we have to partition the data, just
as we partition the functions. So we have green data and red data,
probably implemented as wrappers around the real data types. Green data
can be implicitly converted to red data, but to go the other way will
require some kind of explict syntax, e.g., a cast or a function call on the
wrapper (similar to how smart pointers typically offer a "get" function to
grab the underlying dumb pointer). Again, all similar to how we currently
deal with const.

All function parameters are data, so to answer your question, I'm thinking
that if it were permissible for the scenario you describe to occur, the
type of the parameter would be "red wrapper around a function pointer,"
thus providing a visual cue in the green code that something red was being
handled. We could also offer an overload that took a green wrapper around
a function pointer, thus allowing us to distinugish suspect cases from safe
cases.

Again, the goal isn't to absolutely keep things from compiling, it's to
provide some kind of visual feedback when something suspect is taking
place. As I said, much like how we use const now.

Scott

Francis Glassborow

unread,
Feb 14, 2004, 4:51:35 PM2/14/04
to
In message <e0caaad7.04021...@posting.google.com>, Rob Mayoff
<use...@rob.dqd.com> writes

>Scott Meyers <Use...@aristeia.com> wrote in message news:<MPG.1a95b9e49...@news.hevanet.com>...
>
>> To preserve the "greenness" property, green code must call only green code.
>> Red code can do whatever it wants. (Green code is a lot like being const,
>> while red code is a lot like being non-const: const code can call only
>> const code, but non-const code can call anything it wants to.)
>
>If a green function has a function pointer parameter, is a red
>function allowed to call the green function, passing in a pointer to a
>red function?

The major stumbling block for the red/green concept is how the Standard
C++ Library functions/classes should be classified. That leads me to
speculate that the problem is insoluble from a language/library
perspective. I think you need a special code analysis tool that post a
red flag on any source code that calls functions that are not 'green'.
At the bottom you need a database of primitive 'green' functions.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Scott Meyers

unread,
Feb 15, 2004, 6:35:49 AM2/15/04
to
> The major stumbling block for the red/green concept is how the Standard
> C++ Library functions/classes should be classified.

What makes them special? The standard library is just a library. Suppose
I decide that std::vector is green, but nothing else in the library is.
Why can't I just toss a

using std::vector;

into the green namespace?

Again, this is just an idea I have. It may well be seriously flawed. I
haven't written any code. But it does seem to me that it would be nice to
be able to partition code into chunks that do and do not satisfy some
criterion, e.g., thread-safely, exception-safety, approved for use on
project X, etc.

Scott

Francis Glassborow

unread,
Feb 15, 2004, 8:48:40 AM2/15/04
to
In message <MPG.1a983a585...@news.hevanet.com>, Scott Meyers
<Use...@aristeia.com> writes

>> The major stumbling block for the red/green concept is how the Standard
>> C++ Library functions/classes should be classified.
>
>What makes them special? The standard library is just a library. Suppose
>I decide that std::vector is green, but nothing else in the library is.
>Why can't I just toss a
>
> using std::vector;

Well, std::vector is a template so its color would depend, I think, on
the color of the class with which it is instantiated and using
declarations do not allow that level of precision.

The second problem is how to lock out things from the global namespace
(remember that that the color of a function depends on the colors of the
functions it calls. That is an implementation detail and so not normally
visible in all TUs)

>
>into the green namespace?
>
>Again, this is just an idea I have. It may well be seriously flawed. I
>haven't written any code. But it does seem to me that it would be nice to
>be able to partition code into chunks that do and do not satisfy some
>criterion, e.g., thread-safely, exception-safety, approved for use on
>project X, etc.

Indeed it might but I do not see how to get from here to there other
than through specialist tools that do deep code analysis.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Scott Meyers

unread,
Feb 16, 2004, 7:39:05 AM2/16/04
to
> Well, std::vector is a template so its color would depend, I think, on
> the color of the class with which it is instantiated and using
> declarations do not allow that level of precision.

They may not need to. We might just decide that std::vector is color
neutral and will be green if it's instantiated with green types. This is
analogous to how most of the standard library is wrt exception safety. If
we've colored our data types red and green, we'll have the visual cue we're
looking for if we ever try to instantiate std::vector on a red type. That
is, if we see something like "vector<red::wrapper<Sometype> >", we'll
notice the use of the explicit mention of the red namespace.

> The second problem is how to lock out things from the global namespace

I agree that an unqualified use of a name may match a name in the global
namespace. For symbols over which one has control, the solution is to move
them into a namespace. For symbols over which one has no control, I'm not
sure how to deal with this right now. Thanks for pointing this out.

> (remember that that the color of a function depends on the colors of the
> functions it calls.

Not necessarily. If the green criterion is "the smart guy in cubicle 22B
says it's okay," that's all we need to know. For many of us, I think that
if a library vendor told us that their library were, say, thread-safe, we'd
be inclined to take their word for it, once we'd satisfied ourselves that
we agreed on the definition of the term and possibly after we'd done a
little testing of our own on cases that had proved problematic in the past.

Scott

Bill Wade

unread,
Feb 17, 2004, 6:31:13 AM2/17/04
to
Scott Meyers <Use...@aristeia.com> wrote in message news:<MPG.1a95b9e49...@news.hevanet.com>...
> Suppose I have some classes and functions that can be partitioned into
> those that do and do not satisfy some criterion. For example, some are
> "certified" and some are not. Some are thread-safe and some are not. Some
> are portable and some are not. Let's call the code that satisfies the
> criterion the green code and the code that doesn't satisfy it the red code.

To do this right, I think you'd want a way to say "don't implicitly
use the global namespace."
!using ::
For instance, I'd want to assume that global functions are not
thread-safe, until I'd done some validation.

Of course even that doesn't handle various call-back mechanisms,
including virtual functions:

namespace green
{
!using ::
struct foo{ virtual void bar(){} };
void foobar(){ for_every_foo_object_call_bar(); }
}

namespace red
{
using namespace green;

struct redfoo: foo { bar(foo& f){ redstuff(); };
};

Francis Glassborow

unread,
Feb 17, 2004, 9:21:28 AM2/17/04
to
In message <MPG.1a99f1867...@news.hevanet.com>, Scott Meyers
<Use...@aristeia.com> writes

> > (remember that that the color of a function depends on the colors of the
> > functions it calls.
>
>Not necessarily. If the green criterion is "the smart guy in cubicle 22B
>says it's okay," that's all we need to know. For many of us, I think that
>if a library vendor told us that their library were, say, thread-safe, we'd
>be inclined to take their word for it, once we'd satisfied ourselves that
>we agreed on the definition of the term and possibly after we'd done a
>little testing of our own on cases that had proved problematic in the past.

OK, so let me focus on your example. Can a function that calls
non-thread-safe functions itself be thread-safe? I think not. So we are
relying on the assertion of a third party that a function is 'green'
which is OK until we come to mission critical coding where the assertion
better be one made by someone who takes responsibility for the
consequences of it being false.

I can think of several ways of providing red/green classification if
desired but I do not think the fundamentals of C++ provide the requisite
tools to validate such code. [ well it has just crossed my mind that we
could use one of Andrei Alexandresu's template techniques coupled with
complete templatisation of all our code. However I suspect that is not a
path anyone would wish to take:-)]

Given sufficiently powerful version control and analysis tools it is
possible to provide a considerable degree of support for a green/red
code classification but a compiler and linker is, IMO, far from being
enough.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Francis Glassborow

unread,
Feb 17, 2004, 4:44:13 PM2/17/04
to
In message <2bbfa355.04021...@posting.google.com>, Bill Wade
<wa...@stoner.com> writes

>namespace green
>{
> !using ::
> struct foo{ virtual void bar(){} };
> void foobar(){ for_every_foo_object_call_bar(); }
>}

Even if we introduced the concept of a not using declaration I am
absolutely certain that WG21 would only consider a not using directive
one day a year (and we do sometimes meet on that day). Name lookup is
already horrifyingly complicated without trying that.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Stephen Howe

unread,
Feb 18, 2004, 6:15:01 AM2/18/04
to
>... and since some green code has to call some red code

Why is it necessary for green code to be able call red code?

If it becomes absolutely crucial that some green code needs to call some red
code, then to preserve this invariant (and it is worth preserving), it will
be necessary to look at the red code and see what stops it from being
upgraded to green or to be able call, possibly a cut-down version of the
function which is green.

Stephen Howe

Scott Meyers

unread,
Feb 18, 2004, 7:02:55 AM2/18/04
to
On 17 Feb 2004 09:21:28 -0500, Francis Glassborow wrote:
> OK, so let me focus on your example. Can a function that calls
> non-thread-safe functions itself be thread-safe? I think not. So we are
> relying on the assertion of a third party that a function is 'green'
> which is OK until we come to mission critical coding where the assertion
> better be one made by someone who takes responsibility for the
> consequences of it being false.

There are two separate issues here. One is how we go about certifying
whether code is green or not. The other is how we express the results of
such certification in code and try to prevent people from accidently
straying outside of green code. My namespace application idea only
attempts to address the latter issue.

> I can think of several ways of providing red/green classification if
> desired but I do not think the fundamentals of C++ provide the requisite
> tools to validate such code. [ well it has just crossed my mind that we
> could use one of Andrei Alexandresu's template techniques coupled with
> complete templatisation of all our code. However I suspect that is not a
> path anyone would wish to take:-)]

I'd be interested to see you sketch the route.

Scott

Scott Meyers

unread,
Feb 18, 2004, 7:04:12 AM2/18/04
to
On 17 Feb 2004 06:31:13 -0500, Bill Wade wrote:
> namespace green
> {
> !using ::
> struct foo{ virtual void bar(){} };
> void foobar(){ for_every_foo_object_call_bar(); }
> }
>
> namespace red
> {
> using namespace green;
> struct redfoo: foo { bar(foo& f){ redstuff(); };
> };

I'd call this just a constraint violation: part of green::foo::bar's
interface is to not do non-green stuff. Yes, it would be nice to find a
way to have the compiler detect such a violation, but it is, to me, not the
same as having somebody in the green namespace call into the red namespace
directly.

Issues like calls into the global namespace and calls via virtual functions
or function pointers are interesting and worthy of consideration, but my
perspective on the issue is that it would be worthwhile to be able to
arbitrarily partition code such that likely violations of the partitioning
rules would be flagged during compilation. Right now, we have nothing.
The namespace approach I've described seems to me like it would help catch
errors in a reasonable proportion of the cases. So we'd have something.
We wouldn't have everything, but something is typically better than
nothing.

Also, my original posting asked for other examples of "namespace
applications." Are there none?

Scott

PETER_

unread,
Feb 18, 2004, 7:11:43 AM2/18/04
to
Scott Meyers <Use...@aristeia.com> wrote in message news:<MPG.1a95b9e49...@news.hevanet.com>...
> Suppose I have some classes and functions that can be partitioned into
> those that do and do not satisfy some criterion. For example, some are
> "certified" and some are not. Some are thread-safe and some are not. Some
> are portable and some are not. Let's call the code that satisfies the
> criterion the green code and the code that doesn't satisfy it the red code.
>
> To preserve the "greenness" property, green code must call only green code.
> Red code can do whatever it wants. (Green code is a lot like being const,
> while red code is a lot like being non-const: const code can call only
> const code, but non-const code can call anything it wants to.)
>
> I'd like to have a way to (1) prevent people from accidently modifying
> green code to call red code and (2) to easily find places where a conscious
> decision has been made have green code call red code. The idea I came up
> with was to use namespaces for this. Green code goes in the green
> namespace. Red code goes in the red namespace, but it uses a using
> directive to haul the green namespace in, too:
>
In (1) you sound like you want some kind of compile-time in scope
names constraint policy available to the namespace construct of the
language. How will that not cause confusion with the openedness of
namespaces?

In (2) it sounds like you want a mechanism to defeat that of (1) for
those exceptional cases where the green code's design is flawed or
dependent and requires names from policy hidden foreign scopes. Is
this reasonable? Probably.

I think what you are trying to propose is some kind of construct like
a compile-time package with authored import, export or semantics
policies.
So my question is... What expressiveness are you looking for outside
of the realm of the functional language expressiveness of template
features in the current language? IMO, the proposal seems to imply a
desire to extend the language for new compile-time constraints, but
what kind of constraints and for what purpose and with what kind of
syntatic benefits?

But, since I'm not an standard expert, I unaware of any current WG??
proposals of this nature. Also I know that I've seen one web page
with a quote from Bjarne that, IIRC, a best approach to adding
constraints to C++ has yet to precipitate from its experts.


__PETER (Peter Evans)

Francis Glassborow

unread,
Feb 18, 2004, 6:15:50 PM2/18/04
to
In message <MPG.1a9c3bff9...@news.hevanet.com>, Scott Meyers
<Use...@aristeia.com> writes

> > I can think of several ways of providing red/green classification if
> > desired but I do not think the fundamentals of C++ provide the requisite
> > tools to validate such code. [ well it has just crossed my mind that we
> > could use one of Andrei Alexandresu's template techniques coupled with
> > complete templatisation of all our code. However I suspect that is not a
> > path anyone would wish to take:-)]
>
>I'd be interested to see you sketch the route.

First create an enum:

enum color{red, green};
Now provide a template declaration:

template<color> struct color_ok;

Now specialise it:

template<> struct<green> {};

Now templatise everything else with a color_ok parameter defaulting to
green for green functions and red for red ones [I would have to check
whether the latter only generates a diagnostic if an attempt is made to
call the function with the default argument.]

...
However even if we could get this all to work, it is still not a route
anyone would want to follow.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Sven Rosvall

unread,
Feb 23, 2004, 6:38:37 AM2/23/04
to
Scott Meyers <Use...@aristeia.com> writes:

>Suppose I have some classes and functions that can be partitioned into
>those that do and do not satisfy some criterion. For example, some are
>"certified" and some are not. Some are thread-safe and some are not. Some
>are portable and some are not. Let's call the code that satisfies the
>criterion the green code and the code that doesn't satisfy it the red code.

Interesting idea. I can see more applications for this. Add reviewed
code to the list.

>I'd like to have a way to (1) prevent people from accidently modifying
>green code to call red code and (2) to easily find places where a conscious
>decision has been made have green code call red code. The idea I came up
>with was to use namespaces for this. Green code goes in the green
>namespace. Red code goes in the red namespace, but it uses a using
>directive to haul the green namespace in, too:

I think the namespace mechanism is a bit too cumbersome. It adds a
burden to the code.

Coming from a static analysis background I'd like to propose an
alternative approach. Static analysers can easily generate a call
graph showing all function calls made. A database may contain the
"green" functions. It may also contain wildcards such as "std::*". It
is then easy to go through the database to see if any "green" function
calls any "non-green" function.
--

Allan W

unread,
Feb 26, 2004, 9:20:56 PM2/26/04
to
kcli...@hotmail.com (Kevin Cline) wrote

> Alternatively, you could add prefixes or suffixes to namespaces
> containing red code:
>
> namespace middle_tu_eu_uc { // thread-unsafe, exception_unsafe,
> uncertified
> }

Depending on what "Uncertified" means, it's probably a bad idea to put
it into a (namespace or other) name in code. If we might certify the
code at a later date, we'll have to go change the name of this
namespace. This not only disrupts all users of the code, but it might
mean that we need to certify the code again!

Perhaps you'll use a prefix to indicate that we never do intend to
certify the code, as opposed to code that we either have certified or
plan to certify later.

Reply all
Reply to author
Forward
0 new messages