 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Scott Meyers Guest
|
Posted: Fri Feb 13, 2004 11:17 am Post subject: Using namespaces to partition code |
|
|
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:tempfoo.cpp(34): warning C4717:
'green::greenFunc': recursive on all control paths,
function will cause runtime stack overflow
d:tempfoo.cpp(3 : 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! ]
|
|
| Back to top |
|
 |
Rob Mayoff Guest
|
Posted: Sat Feb 14, 2004 12:38 am Post subject: Re: Using namespaces to partition code |
|
|
Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote
| Quote: | 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?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kevin Cline Guest
|
Posted: Sat Feb 14, 2004 12:26 pm Post subject: Re: Using namespaces to partition code |
|
|
Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote
| Quote: | 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?
|
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
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Scott Meyers Guest
|
Posted: Sat Feb 14, 2004 2:22 pm Post subject: Re: Using namespaces to partition code |
|
|
On 13 Feb 2004 19:38:42 -0500, Rob Mayoff wrote:
| Quote: | 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sat Feb 14, 2004 9:51 pm Post subject: Re: Using namespaces to partition code |
|
|
In message <e0caaad7.0402130641.1f1f5a48 (AT) posting (DOT) google.com>, Rob Mayoff
<usenet (AT) rob (DOT) dqd.com> writes
| Quote: | Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Scott Meyers Guest
|
Posted: Sun Feb 15, 2004 11:35 am Post subject: Re: Using namespaces to partition code |
|
|
| Quote: | 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Feb 15, 2004 1:48 pm Post subject: Re: Using namespaces to partition code |
|
|
In message <MPG.1a983a585231ab65989728 (AT) news (DOT) hevanet.com>, Scott Meyers
<Usenet (AT) aristeia (DOT) com> writes
| Quote: | 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)
| Quote: |
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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Scott Meyers Guest
|
Posted: Mon Feb 16, 2004 12:39 pm Post subject: Re: Using namespaces to partition code |
|
|
| Quote: | 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", we'll
notice the use of the explicit mention of the red namespace.
| Quote: | 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.
| Quote: | (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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bill Wade Guest
|
Posted: Tue Feb 17, 2004 11:31 am Post subject: Re: Using namespaces to partition code |
|
|
Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote
| Quote: | 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(); };
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Tue Feb 17, 2004 2:21 pm Post subject: Re: Using namespaces to partition code |
|
|
In message <MPG.1a99f18675ea165398972b (AT) news (DOT) hevanet.com>, Scott Meyers
<Usenet (AT) aristeia (DOT) com> writes
| Quote: | (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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Tue Feb 17, 2004 9:44 pm Post subject: Re: Using namespaces to partition code |
|
|
In message <2bbfa355.0402160548.1681bcb6 (AT) posting (DOT) google.com>, Bill Wade
<wade (AT) stoner (DOT) com> writes
| Quote: | 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Stephen Howe Guest
|
Posted: Wed Feb 18, 2004 11:15 am Post subject: Re: Using namespaces to partition code |
|
|
| Quote: | ... 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Scott Meyers Guest
|
Posted: Wed Feb 18, 2004 12:02 pm Post subject: Re: Using namespaces to partition code |
|
|
On 17 Feb 2004 09:21:28 -0500, Francis Glassborow wrote:
| Quote: | 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.
| Quote: | 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Scott Meyers Guest
|
Posted: Wed Feb 18, 2004 12:04 pm Post subject: Re: Using namespaces to partition code |
|
|
On 17 Feb 2004 06:31:13 -0500, Bill Wade wrote:
| Quote: | 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
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
PETER_ Guest
|
Posted: Wed Feb 18, 2004 12:11 pm Post subject: Re: Using namespaces to partition code |
|
|
Scott Meyers <Usenet (AT) aristeia (DOT) com> wrote
| Quote: | 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)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|