Topic: C++0x wish: pre-declaration of inheritance
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Fri, 8 Jun 2001 19:23:22 GMT Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3B1FB6C1.7F2826AE@acm.org...
> Al Grant wrote:
> > > Well, fine, but in order for the compiler to detect a violation of
this
> > > new rule, as in the code example, the compiler has to do a bunch of
> > > cross-module bookkeeping that is not currently required.
> >
> > I'm not suggesting it has to be detected.
>
> I thought that was what you meant when you said
>
> > > > > Al Grant wrote:
> > > > > > I mean, does it matter that certain cases will fail
> > > > > > the assertion, as long as they can be detected?
>
> If you don't care about detection, then I've wasted my time in this
> discussion.
I care about detecting when an implementation violates an
assertion that is made by the interface it has declared.
I don't care about detecting when an implementation doesn't
see its own declared interface, or sees the wrong one.
It's like if you declare a function in your public header
file, with C linkage, taking ptr-to-const arguments, and
then defined it, without including that header file,
as taking ptr-to-non-const arguments. I've seen that done,
in a major vendor's SDK. I don't think it's the compiler's
job to detect that either.
If you regard assertion that an upcast is free, as a
part of the definition of a struct, then making that
assertion in one unit and saying something else
incompatible with it in another, as in your example,
is just a failure of the one-definition rule, which
the compiler is not obliged to detect.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Thu, 7 Jun 2001 16:45:45 GMT Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3B1E5FD5.2BCDDA16@acm.org...
> Al Grant wrote:
> > "Pete Becker" <petebecker@acm.org> wrote in message
> > news:3B1D2D9B.CC2C55C7@acm.org...
> > > Al Grant wrote:
> > > > I mean, does it matter that certain cases will fail
> > > > the assertion, as long as they can be detected?
> > >
> > > Guaranteeing detection precludes separate compilation.
> > >
> > > // file1.cpp
> > > class A;
> > > class B : public A;
> > >
> > > // file2.cpp
> > > class A {};
> > > class B : public virtual A {};
> > >
> > > That violation of this proposed rule would be undetectable unless the
> > > compiler did a bunch of cross-module bookkeeping that is not currently
> > > required.
> >
> > If you use the assertion in one unit, you've got to use
> > it in the unit that you actually fully declare the
> > classes in.
>
> Well, fine, but in order for the compiler to detect a violation of this
> new rule, as in the code example, the compiler has to do a bunch of
> cross-module bookkeeping that is not currently required.
I'm not suggesting it has to be detected. Your code
example would be non-conforming. If you want the assertion
to be verified against the definition you have to make sure
they are seen in the same unit. Otherwise it is your
responsibility to ensure that the assertion reflects the
reality of the definition.
The compiler is not obliged to detect all violations of
the one-definition rule by cross-module bookkeeping, is it?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: Thu, 7 Jun 2001 18:40:36 GMT Raw View
Al Grant wrote:
>
> "Pete Becker" <petebecker@acm.org> wrote in message
> news:3B1E5FD5.2BCDDA16@acm.org...
> > Al Grant wrote:
> > > "Pete Becker" <petebecker@acm.org> wrote in message
> > > news:3B1D2D9B.CC2C55C7@acm.org...
> > > > Al Grant wrote:
> > > > > I mean, does it matter that certain cases will fail
> > > > > the assertion, as long as they can be detected?
> > > >
> > > > Guaranteeing detection precludes separate compilation.
> > > >
> > > > // file1.cpp
> > > > class A;
> > > > class B : public A;
> > > >
> > > > // file2.cpp
> > > > class A {};
> > > > class B : public virtual A {};
> > > >
> > > > That violation of this proposed rule would be undetectable unless the
> > > > compiler did a bunch of cross-module bookkeeping that is not currently
> > > > required.
> > >
> > > If you use the assertion in one unit, you've got to use
> > > it in the unit that you actually fully declare the
> > > classes in.
> >
> > Well, fine, but in order for the compiler to detect a violation of this
> > new rule, as in the code example, the compiler has to do a bunch of
> > cross-module bookkeeping that is not currently required.
>
> I'm not suggesting it has to be detected.
I thought that was what you meant when you said
> > > > Al Grant wrote:
> > > > > I mean, does it matter that certain cases will fail
> > > > > the assertion, as long as they can be detected?
If you don't care about detection, then I've wasted my time in this
discussion.
> Your code
> example would be non-conforming. If you want the assertion
> to be verified against the definition you have to make sure
> they are seen in the same unit. Otherwise it is your
> responsibility to ensure that the assertion reflects the
> reality of the definition.
>
> The compiler is not obliged to detect all violations of
> the one-definition rule by cross-module bookkeeping, is it?
>
No, it's not. But if you don't care about detectability then you don't
need a language extension. Just use reinterpret_cast.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Tue, 5 Jun 2001 14:40:22 GMT Raw View
"Ron Natalie" <ron@spamcop.net> wrote in message
news:3B1BD54A.A6BAFB0D@spamcop.net...
> Al Grant wrote:
> > I want to be able to say
> > struct A;
> > struct B: A;
> > A *f(B *b) { return b; }
> >
> > Such a declaration would assert that the cast is a null
> > operation, and the subsequent full declaration of the
> > structs, wherever it was, would be an error if the cast
> > turned out not to be a null operation.
>
> How do you know it's a null operation? While there's an
> implicit conversion there, nothing says that the that b
> and (A*)b are null operations in general. Unless you are
> going to force more restrictions on the implementation of
> classes in memory than there are now, it would be an
> implementation defined issue as to whether code written
> in such a way would return an error or not.
I think the C++ standard should state that certain kinds
of up-cast (when the fields and inheritance relationships
are of certain kinds) are guranateed to be null operations,
and then it could be an error if the definitions, when
encountered, were not of those kinds.
For example if I declare
struct A;
struct B: A;
struct A { int x; };
struct B: A { int y; };
is it unreasonable to guarantee that casting a B* to an A*
will be a null operation? Do you mean the pointers may be
tagged with e.g. object type or size?
> Furthermore, you have no way to tell if "struct A;" is an
> existing incomplete declaration (with unknown inheritance)
> or your new incomplete declaration with no base classes.
Does it matter? Something somewhere is going to see the
definitions and detect whether casting A* to B* is guaranteed
to be null. Of course for this to work, it must also see
the incomplete declarations, since they make the assertion.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Tue, 5 Jun 2001 15:37:18 GMT Raw View
Al Grant wrote:
>
> I think the C++ standard should state that certain kinds
> of up-cast (when the fields and inheritance relationships
> are of certain kinds) are guranateed to be null operations,
> and then it could be an error if the definitions, when
> encountered, were not of those kinds.
There is no such statement in the standard. Do not confuse
implicit conversion with doing NOTHING.
>
> For example if I declare
> struct A;
> struct B: A;
> struct A { int x; };
> struct B: A { int y; };
> is it unreasonable to guarantee that casting a B* to an A*
> will be a null operation? Do you mean the pointers may be
> tagged with e.g. object type or size?
No it is not (ignorning the bogus partial declaration above).
It's quite possible that B::y comes before A::x in memory.
>
> > Furthermore, you have no way to tell if "struct A;" is an
> > existing incomplete declaration (with unknown inheritance)
> > or your new incomplete declaration with no base classes.
>
> Does it matter? Something somewhere is going to see the
> definitions and detect whether casting A* to B* is guaranteed
> to be null. Of course for this to work, it must also see
> the incomplete declarations, since they make the assertion.
>
Of course it matters. What happens if A has base classes. A
virtual base class will certainly blow holes in most systems.
If a class Z inherits from X and Y:
struct Z : X, Y {
};
The compiler might put X first, it might put Y first. There's no
statement as to the arrangement.
Since the layout of data in a struct with inheritance is implementation
defined, it is implementation defined as to whether the conversion is
a nop
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Tue, 5 Jun 2001 18:42:24 GMT Raw View
"Ron Natalie" <ron@spamcop.net> wrote in message
news:3B1CF3BB.2CA8C3F@spamcop.net...
> Al Grant wrote:
> > I think the C++ standard should state that certain kinds
> > of up-cast (when the fields and inheritance relationships
> > are of certain kinds) are guranateed to be null operations,
>
> There is no such statement in the standard.
I know. But there could be. We should have guarantees
that operations will be free if there is no reason for
them not to be.
> > For example if I declare
> > struct A;
> > struct B: A;
> > struct A { int x; };
> > struct B: A { int y; };
> > is it unreasonable to guarantee that casting a B* to an A*
> > will be a null operation? Do you mean the pointers may be
> > tagged with e.g. object type or size?
>
> No it is not (ignorning the bogus partial declaration above).
> It's quite possible that B::y comes before A::x in memory.
Why not disallow that?
> > > Furthermore, you have no way to tell if "struct A;" is an
> > > existing incomplete declaration (with unknown inheritance)
> > > or your new incomplete declaration with no base classes.
> >
> > Does it matter? Something somewhere is going to see the
> > definitions and detect whether casting A* to B* is guaranteed
> > to be null. Of course for this to work, it must also see
> > the incomplete declarations, since they make the assertion.
> >
> Of course it matters. What happens if A has base classes. A
> virtual base class will certainly blow holes in most systems.
I mean, does it matter that certain cases will fail
the assertion, as long as they can be detected?
If I have asserted that the upcast will be a nop
and there is at least one program unit that sees the
assertion and also sees that the upcast cannot be a
nop, and causes the compilation (even if only of that
unit) to fail, then I am happy.
> If a class Z inherits from X and Y:
>
> struct Z : X, Y {
> };
>
> The compiler might put X first, it might put Y first. There's no
> statement as to the arrangement.
It could make such a statement (about upcasting
from Z* to X*) with appropriate restrictions on the
nature of Z and X. If it had been previously
asserted that the upcast from Z* to X* was a nop,
and then these restrictions were not fulfilled,
that would be an error.
> Since the layout of data in a struct with inheritance is implementation
> defined, it is implementation defined as to whether the conversion is
> a nop
Well, I'm suggesting a modification to the standard
and that includes any changes necessary to achieve
that. If the standard is leaving things as
implementation defined when by standardising them
it could make efficiency guarantees that could be
exploited by the programmer, and there is no
technical reason not to make those guarantees,
then let's have it make them.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Tue, 5 Jun 2001 20:47:55 GMT Raw View
Al Grant wrote:
> > are of certain kinds) are guranateed to be null operations,
> >
> > There is no such statement in the standard.
>
> I know. But there could be. We should have guarantees
> that operations will be free if there is no reason for
> them not to be.
You're crossing the line into forcing a lot of implementation
issues that C++ has generally not touched. In general it's
safer to believe that there is some conversion occuring to the
value when doing implicit convesions even when such might not
be the case.
> > > Does it matter? Something somewhere is going to see the
> > > definitions and detect whether casting A* to B* is guaranteed
> > > to be null. Of course for this to work, it must also see
> > > the incomplete declarations, since they make the assertion.
> > >
> > Of course it matters. What happens if A has base classes. A
> > virtual base class will certainly blow holes in most systems.
>
> I mean, does it matter that certain cases will fail
> the assertion, as long as they can be detected?
> If I have asserted that the upcast will be a nop
> and there is at least one program unit that sees the
> assertion and also sees that the upcast cannot be a
> nop, and causes the compilation (even if only of that
> unit) to fail, then I am happy.
Even if you go ahead with your idea, you still need a way to
tell the difference between a forward declaration decaring
NO BASE CLASSES and one declaring unspecified inheritance.
Otherwise, even with a rigorous layout rule as proposed, you
still can't make the determination if the B* to A* conversion is
a noop.
I suppose you could say:
struct A : ; // no base classes.
struct X ; // unknown inheritance heirarchy
struct B : A ;
> Well, I'm suggesting a modification to the standard
> and that includes any changes necessary to achieve
> that. If the standard is leaving things as
> implementation defined when by standardising them
> it could make efficiency guarantees that could be
> exploited by the programmer, and there is no
> technical reason not to make those guarantees,
> then let's have it make them.
>
What efficiency guarantee? Just because you think that
the layout makes sense to you doesn't mean it needs to be
cast in stone for all implementations. Perhaps it's more
efficient for some implementation to use another layout.
This isn't an efficiency issue at all but an implementation
hiding issue. Frankly, I can envision much better ideas than
this.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: Tue, 5 Jun 2001 23:13:08 GMT Raw View
Al Grant wrote:
>
> "Ron Natalie" <ron@spamcop.net> wrote in message
> news:3B1CF3BB.2CA8C3F@spamcop.net...
> > Al Grant wrote:
> > > I think the C++ standard should state that certain kinds
> > > of up-cast (when the fields and inheritance relationships
> > > are of certain kinds) are guranateed to be null operations,
> >
> > There is no such statement in the standard.
>
> I know. But there could be. We should have guarantees
> that operations will be free if there is no reason for
> them not to be.
>
> > > For example if I declare
> > > struct A;
> > > struct B: A;
> > > struct A { int x; };
> > > struct B: A { int y; };
> > > is it unreasonable to guarantee that casting a B* to an A*
> > > will be a null operation? Do you mean the pointers may be
> > > tagged with e.g. object type or size?
> >
> > No it is not (ignorning the bogus partial declaration above).
> > It's quite possible that B::y comes before A::x in memory.
>
> Why not disallow that?
Because it allows compiler implementors flexibility to make things more
efficient.
>
> > > > Furthermore, you have no way to tell if "struct A;" is an
> > > > existing incomplete declaration (with unknown inheritance)
> > > > or your new incomplete declaration with no base classes.
> > >
> > > Does it matter? Something somewhere is going to see the
> > > definitions and detect whether casting A* to B* is guaranteed
> > > to be null. Of course for this to work, it must also see
> > > the incomplete declarations, since they make the assertion.
> > >
> > Of course it matters. What happens if A has base classes. A
> > virtual base class will certainly blow holes in most systems.
>
> I mean, does it matter that certain cases will fail
> the assertion, as long as they can be detected?
Guaranteeing detection precludes separate compilation.
// file1.cpp
class A;
class B : public A;
// file2.cpp
class A {};
class B : public virtual A {};
That violation of this proposed rule would be undetectable unless the
compiler did a bunch of cross-module bookkeeping that is not currently
required.
> If I have asserted that the upcast will be a nop
> and there is at least one program unit that sees the
> assertion and also sees that the upcast cannot be a
> nop, and causes the compilation (even if only of that
> unit) to fail, then I am happy.
>
> > If a class Z inherits from X and Y:
> >
> > struct Z : X, Y {
> > };
> >
> > The compiler might put X first, it might put Y first. There's no
> > statement as to the arrangement.
>
> It could make such a statement (about upcasting
> from Z* to X*) with appropriate restrictions on the
> nature of Z and X. If it had been previously
> asserted that the upcast from Z* to X* was a nop,
> and then these restrictions were not fulfilled,
> that would be an error.
If it was detected. But typically it wouldn't be, and this would simply
be a way of setting traps for unwary programmers.
>
> > Since the layout of data in a struct with inheritance is implementation
> > defined, it is implementation defined as to whether the conversion is
> > a nop
>
> Well, I'm suggesting a modification to the standard
> and that includes any changes necessary to achieve
> that. If the standard is leaving things as
> implementation defined when by standardising them
> it could make efficiency guarantees that could be
> exploited by the programmer, and there is no
> technical reason not to make those guarantees,
> then let's have it make them.
>
That is, this would enable programmers to make minor assertions about
efficiency while making compilers much more complex and limiting what
they can do to generate more efficient code.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Mon, 4 Jun 2001 17:50:00 GMT Raw View
I want to be able to say
struct A;
struct B: A;
A *f(B *b) { return b; }
Such a declaration would assert that the cast is a null
operation, and the subsequent full declaration of the
structs, wherever it was, would be an error if the cast
turned out not to be a null operation.
This would allow inheritance relationships of opaque
pointers to be exposed without exposing the implementation.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Mon, 4 Jun 2001 20:04:57 GMT Raw View
Al Grant wrote:
>
> I want to be able to say
>
> struct A;
> struct B: A;
> A *f(B *b) { return b; }
>
> Such a declaration would assert that the cast is a null
> operation, and the subsequent full declaration of the
> structs, wherever it was, would be an error if the cast
> turned out not to be a null operation.
>
How do you know it's a null operation? While there's an
implicit conversion there, nothing says that the that b
and (A*)b are null operations in general. Unless you are
going to force more restrictions on the implementation of
classes in memory than there are now, it would be an
implementation defined issue as to whether code written
in such a way would return an error or not.
Furthermore, you have no way to tell if "struct A;" is an
existing incomplete declaration (with unknown inheritance)
or your new incomplete declaration with no base classes.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Al Grant" <tnarga@arm.REVERSE-NAME.com>
Date: Wed, 6 Jun 2001 16:19:37 GMT Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3B1D2D9B.CC2C55C7@acm.org...
> Al Grant wrote:
> > I mean, does it matter that certain cases will fail
> > the assertion, as long as they can be detected?
>
> Guaranteeing detection precludes separate compilation.
>
> // file1.cpp
> class A;
> class B : public A;
>
> // file2.cpp
> class A {};
> class B : public virtual A {};
>
> That violation of this proposed rule would be undetectable unless the
> compiler did a bunch of cross-module bookkeeping that is not currently
> required.
If you use the assertion in one unit, you've got to use
it in the unit that you actually fully declare the
classes in. So file2.cpp would have to see
class A;
class B : public A;
class A {};
class B : public virtual A {};
and would fail, given a rule that virtual inheritance was
incompatible with the assertion that the upcast was a nop.
> That is, this would enable programmers to make minor assertions about
> efficiency while making compilers much more complex and limiting what
> they can do to generate more efficient code.
The intention is that you can declare inheritance relationships
and have safe zero-cost upcasting, instead of using unsafe casts
to achieve the same thing. Instead of writing
struct AnExprNode;
struct ABinaryExprNode;
inline AnExprNode * as_expr(ABinaryExprNode *p)
{
return (AnExprNode *)p;
}
you just write
struct AnExprNode;
struct ABinaryExprNode: AnExprNode;
If you don't like restricting certain kinds of inheritance
to have zero-cost upcasts even in the absence of the
programmer asserting that they do, then why not just put
that restriction on when you make the assertion?
So the assertion just states that you want the inheritance
implemented in a particular way.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "David Abrahams" <abrahams@mediaone.net>
Date: Wed, 6 Jun 2001 20:17:44 GMT Raw View
"Al Grant" <tnarga@arm.REVERSE-NAME.com> wrote in message
news:9ffjv8$cb0$1@cam-news1.cambridge.arm.com...
> I want to be able to say
>
> struct A;
> struct B: A;
> A *f(B *b) { return b; }
>
> Such a declaration would assert that the cast is a null
> operation, and the subsequent full declaration of the
> structs, wherever it was, would be an error if the cast
> turned out not to be a null operation.
>
> This would allow inheritance relationships of opaque
> pointers to be exposed without exposing the implementation.
Do you really want that, or do you want some way to reduce compilation times
and dependencies? If the above is just an attempt to get the latter, I think
it's a half-measure. It would be better to consider what it would take to
support compilation models that make your real goal easier to achieve.
Several of us believe that the header file/preprocessor/translation unit
model imposes too many avoidable costs on programmers, and are thinking
about ways around those problems.
-Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: Wed, 6 Jun 2001 20:18:34 GMT Raw View
Al Grant wrote:
>
> "Pete Becker" <petebecker@acm.org> wrote in message
> news:3B1D2D9B.CC2C55C7@acm.org...
> > Al Grant wrote:
> > > I mean, does it matter that certain cases will fail
> > > the assertion, as long as they can be detected?
> >
> > Guaranteeing detection precludes separate compilation.
> >
> > // file1.cpp
> > class A;
> > class B : public A;
> >
> > // file2.cpp
> > class A {};
> > class B : public virtual A {};
> >
> > That violation of this proposed rule would be undetectable unless the
> > compiler did a bunch of cross-module bookkeeping that is not currently
> > required.
>
> If you use the assertion in one unit, you've got to use
> it in the unit that you actually fully declare the
> classes in.
Well, fine, but in order for the compiler to detect a violation of this
new rule, as in the code example, the compiler has to do a bunch of
cross-module bookkeeping that is not currently required.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]