 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Joe Chen Guest
|
Posted: Mon Jul 05, 2004 10:08 am Post subject: Const Reference Return Efficiency |
|
|
Hello,
I have recently seen code written like the following:
class A {
public:
const std::string& getValue() { return value_; }
protected:
std::string value_;
};
const std::string& val = myA.getValue();
with the argument that returning by const reference
avoids the temporary construction/destruction of the returned
string and a copy constructor call for the return, if it
were returned by value - hence being more efficient.
Seeing how I cringe at premature optimization, I have a few
concerns/questions about this I was hoping the community
could help me with.
1. Since most modern compilers with do RVO on the getValue and
possibly eliminate the temporary, is avoiding the copy construction
on a return by value worth code that is encapsulation messy? I
feel uncomfortable revealing the internals of my class, or
introducting confusing lifetime symantics of the member variables
inside.
2. Will this prevent other compiler optimizations due to aliasing?
My suspicion is that since the compiler can never know how many
references to the internal representation there are, it is possible
the code is missing out on optimizations greater than what the
missing copy constructor provides.
3. Unless this is required by being in a large, tight loop and a
profiler deems it necessary, I feel that the cost of a copy construction
of the string if returned by value would be completely swamped by
other calculations done within a function and probably wouldn't
effect the overal profile. Therefore, it loses out on solid OO
encapsulation and flexibility at the cost of mistaken effciency.
What are you thoughts?
Thanks!
[ 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: Mon Jul 05, 2004 3:01 pm Post subject: Re: Const Reference Return Efficiency |
|
|
In article <6766c4c.0407041316.6d02b734 (AT) posting (DOT) google.com>, Joe Chen
<joe_w_chen (AT) hotmail (DOT) com> writes
| Quote: | I have recently seen code written like the following:
class A {
public:
const std::string& getValue() { return value_; }
protected:
std::string value_;
};
const std::string& val = myA.getValue();
with the argument that returning by const reference
avoids the temporary construction/destruction of the returned
string and a copy constructor call for the return, if it
were returned by value - hence being more efficient.
|
Yes that is a very common C++ idiom.
| Quote: |
Seeing how I cringe at premature optimization, I have a few
concerns/questions about this I was hoping the community
could help me with.
|
I wonder if this is really a case of premature optimisation.
| Quote: |
1. Since most modern compilers with do RVO on the getValue and
possibly eliminate the temporary, is avoiding the copy construction
on a return by value worth code that is encapsulation messy? I
feel uncomfortable revealing the internals of my class, or
introducting confusing lifetime symantics of the member variables
inside.
|
There is no conceivable way that a compiler can optimise away all copies
if you return by value. To see why, consider your example. If the string
were returned by value, that value will have to exist throughout the
lifetime of val. That means that it must have a lifetime that is not
dependant on the lifetime of myA.
Of course in the example above there is the potential for a hanging
reference but the programmer knows that because of the signature of
A::getValue(). Change that return to a return by value and there is not
such implication.
| Quote: |
2. Will this prevent other compiler optimizations due to aliasing?
My suspicion is that since the compiler can never know how many
references to the internal representation there are, it is possible
the code is missing out on optimizations greater than what the
missing copy constructor provides.
|
Actually the real cost of const references is much subtler though still
related to aliasing. The problem occurs because C++ allows global
variables as well as separate TUs. This means that the compiler always
has to assume that const references may in fact mutate unless it can
proof otherwise.
int foo(mytype const & mt){
// do things without function calls
// optimiser can assume mt is actually immutable
bar();
// unless the compiler can see the implementation of bar()
// or knows that mt cannot be a reference to a global
// on return from bar() it must assume that mt may have changed
}
| Quote: |
3. Unless this is required by being in a large, tight loop and a
profiler deems it necessary, I feel that the cost of a copy construction
of the string if returned by value would be completely swamped by
other calculations done within a function and probably wouldn't
effect the overal profile. Therefore, it loses out on solid OO
encapsulation and flexibility at the cost of mistaken effciency.
|
Using the small string optimisation [premature? ] assuming the string
is small the cost of copying may be small but in general std::string
uses dynamic memory and that is often expensive.
| Quote: |
What are you thoughts?
|
It is the job of a class designer to have sufficient understanding of
implementation to identify when return by value is appropriate. Of
course not all class designers exercise such care and attention to
detail, but those that do should not be open to criticism for premature
optimisation. Not all optimisation is premature. This is particularly
the case for third party libraries where the library designer has little
if any knowledge of how the library will be used.
--
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 |
|
 |
Antoun Kanawati Guest
|
Posted: Mon Jul 05, 2004 6:59 pm Post subject: Re: Const Reference Return Efficiency |
|
|
Joe Chen wrote:
| Quote: | Hello,
I have recently seen code written like the following:
class A {
public:
const std::string& getValue() { return value_; }
protected:
std::string value_;
};
const std::string& val = myA.getValue();
with the argument that returning by const reference
avoids the temporary construction/destruction of the returned
string and a copy constructor call for the return, if it
were returned by value - hence being more efficient.
Seeing how I cringe at premature optimization, I have a few
concerns/questions about this I was hoping the community
could help me with.
|
The reservation on premature optimization is a rule of thumb, not
an article of faith.
When looking at such an issue, you have to temper your view with
the considerations of good design.
In this particular case, the usage style show below
std::string val = myA.getValue();
addresses all your concerns by removing the "const &".
However, you still have *the option* of not copying the string,
if you feel strongly about that.
Hence, one feels "good" about this style because it does not
preclude options that may be important to the user in contexts
that the designer could not have thought of (a common situation
for reusable classes).
Also, when writing reusable libraries, one is often forced
into "absolute optimization", which is even worse than "premature
optimization". Because, unlike application specific libraries,
general purpose libraries must be as universal as possible.
So, in any general purpose library, you'll find more optimization
than any particular profiling session would dictate.
Finally, you should never depend on the optimizer to make the code
qualitatively better; the optimizer is only a fine tuning phase of code
generation, and most of what it does is "optional at the discretion
of the optimizer", that is: may not happen when you want it to.
--
Antoun Kanawati
[email]antounk.at (AT) comcast (DOT) dot.net[/email]
[remove .dot and .at before use]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alex Vinokur Guest
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Mon Jul 05, 2004 10:33 pm Post subject: Re: Const Reference Return Efficiency |
|
|
[email]joe_w_chen (AT) hotmail (DOT) com[/email] (Joe Chen) wrote (abridged):
| Quote: | I have recently seen code written like the following:
class A {
public:
const std::string& getValue() { return value_; }
protected:
std::string value_;
};
|
I would consider that OK.
| Quote: | const std::string& val = myA.getValue();
|
Where-as this is dangerous. Safer to use:
const std::string val = myA.getValue();
so we get our own copy of the string, with no aliases or lifetime
problems.
With a good compiler, in that case, the string will only be copied once
even if we don't return it by reference. However, the reference should be
a benefit in other cases, eg:
size_t len = myA.getValue().size();
To copy the string in this case would be an unnecessary pessimisation. It
would take time O(n) instead of O(1). Generally I prefer fast code, unless
there is a good reason for it to be slow.
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Erik Max Francis Guest
|
Posted: Mon Jul 05, 2004 10:38 pm Post subject: Re: Const Reference Return Efficiency |
|
|
Alex Vinokur wrote:
And in that same thread, someone pointed out the numerous systematic
problems with your analysis.
--
__ Erik Max Francis && [email]max (AT) alcyone (DOT) com[/email] && http://www.alcyone.com/max/
/ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
__/ In time of war the devil makes more room in hell.
-- (a German proverb)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Joe Chen Guest
|
Posted: Mon Jul 05, 2004 10:41 pm Post subject: Re: Const Reference Return Efficiency |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote
| Quote: | Yes that is a very common C++ idiom.
|
Is it typically a good idiom to use for optimization, even though it
returns a handle to internal data? (which I thought was bad).
| Quote: | There is no conceivable way that a compiler can optimise away all copies
if you return by value. To see why, consider your example. If the string
were returned by value, that value will have to exist throughout the
lifetime of val. That means that it must have a lifetime that is not
dependant on the lifetime of myA.
|
Understood. I was concerned that dependent lifetimes and ownership
issues were a large design price to pay for a potentially small
optimization, or an optimization that could have been better.
| Quote: | Actually the real cost of const references is much subtler though still
related to aliasing. The problem occurs because C++ allows global
variables as well as separate TUs. This means that the compiler always
has to assume that const references may in fact mutate unless it can
proof otherwise.
|
I guess this was my original concern. Does this code trade the
optimization of eliminating all copies of the string for possibly
better optimization that could have been done if it was returned by
value? Basically, could the code have been faster if the string was
returned by value?
Thanks,
Joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Nicola Musatti Guest
|
Posted: Tue Jul 06, 2004 11:38 am Post subject: Re: Const Reference Return Efficiency |
|
|
[email]joe_w_chen (AT) hotmail (DOT) com[/email] (Joe Chen) wrote in message news:<6766c4c.0407041316.6d02b734 (AT) posting (DOT) google.com>...
| Quote: | Hello,
I have recently seen code written like the following:
class A {
public:
const std::string& getValue() { return value_; }
protected:
std::string value_;
};
const std::string& val = myA.getValue();
[Very sensible analysis snipped]
What are you thoughts?
|
I think we should concern ourselves more with writing safe code than
with writing supposedly fast code. In order to do so I have a very
simple guideline on the subject:
Never return by reference unless you are returning either *this or an
argument you received by reference.
Those who preach otherwise should remember that the days of few
megahertz clocks and no cache are long gone for the vaste majority of
us.
Cheers,
Nicola Musatti
[ 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 Jul 06, 2004 9:09 pm Post subject: Re: Const Reference Return Efficiency |
|
|
In article <a327cf48.0407060010.1eea2e09 (AT) posting (DOT) google.com>, Nicola
Musatti <Nicola.Musatti (AT) ObjectWay (DOT) it> writes
| Quote: | I think we should concern ourselves more with writing safe code than
with writing supposedly fast code.
|
Agreed.
| Quote: | In order to do so I have a very
simple guideline on the subject:
Never return by reference unless you are returning either *this or an
argument you received by reference.
|
I think that is a poor guideline. A few years ago people would advocate
the use of copy-on-write as a way to achieve good performance even when
passing by value. More recently that idiom has come under close scrutiny
and does not seem to hold up well in multi-threaded environments.
Library implementors have to make careful judgement calls, and the good
ones get it right more often than not and go on learning from
experience.
Now let me give you a direct counter example to your guideline. Consider
a class that has an std::vector member as a repository for a certain
type of data. Now how do I provide access to that data for searching
given that I do not know the general nature of the searches that a user
may wish to implement?
Copying a vector of unknown size can be so expensive as to completely
dominate the performance of an application. The class designer has no
way to know how expensive copying will be, only the user can know that.
Between the issue of how to make available the value of a member of a
builtin type (clearly by value?) and that of a possibly very large
container (clearly by const reference?) there lies a wide intermediate
range. At what point should we switch mechanism? Now throw in
multi-threading to the mix.
The final issue is that objects rather than values are non-copyable. If
we wish to provide read access to an object that is part of a larger
object we often have no choice.
std::string is a special case because conceptually it is value based
even though its potential size often makes it more suitable to handle it
as an object.
| Quote: |
Those who preach otherwise should remember that the days of few
megahertz clocks and no cache are long gone for the vaste majority of
us.
|
But we also deal with immensely larger objects, some of which may be
distributed across the World.
--
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 |
|
 |
Antoun Kanawati Guest
|
Posted: Tue Jul 06, 2004 9:13 pm Post subject: Re: Const Reference Return Efficiency |
|
|
Nicola Musatti wrote:
| Quote: | I think we should concern ourselves more with writing safe code than
with writing supposedly fast code. In order to do so I have a very
simple guideline on the subject:
[snip]
Those who preach otherwise should remember that the days of few
megahertz clocks and no cache are long gone for the vaste majority of
us.
|
I would love to believe that the days of CPU cycle squeezing are gone.
But, they're not.
My first PC was 4.77Mhz/640KB; today, I have a p4/2.8 and 512MB. I
recall distinctly that the old box was reasonably responsive, and became
more so when I boosted it to 8Mhz. Today, I still wait for things to
happen, some programs still feel sluggish, some programs still crash,
though my hardware is thousands of times faster and my memory is
hundreds of times larger than it used to be.
But that's just on the PC (and similar entities). When you're talking
embedded machinery, these assumptions about oodles of mhz and megabytes
are not valid. Today, for each PC, there are several embedded
processors: the digital watch, the microwave, the cell phone, the PDA,
the cable box, the printer, the wireless phone, the caller-id gizmo next
to it, the CD/MP3 player in my car, the car itself, etc... and that was
only a quick glance around the room, and a look at the driveway.
Regarding safety at the expense of speed: assume that the programmer
using your libraries is a professional capable of making professional
and responsible choices. For example, if you use the const-ref return
idiom, and this programmer has a concern with safety, it's very easy
for them to make a copy; but, if they happen to have a need for an
extra cycle or two [copying a std::string is not just a cycle or
two], they'll be happy that they don't have to rewrite your class
to squeeze those cycles out.
If you want a "guiding principle": Do not ever preclude safe (or
optimal) options.
This is quite different from: Provide only the safe option even if it
costs speed and/or memory. You'll never be able to compensate for
irresponsible programming practices, and you'll provide challenges to
the irresponsible macho types that'll create more headaches than the
ones you thought you were avoiding.
--
Antoun Kanawati
[email]antounk.at (AT) comcast (DOT) dot.net[/email]
[remove .dot and .at before use]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Tue Jul 06, 2004 9:15 pm Post subject: Re: Const Reference Return Efficiency |
|
|
[email]Nicola.Musatti (AT) ObjectWay (DOT) it[/email] (Nicola Musatti) writes:
| Quote: | I think we should concern ourselves more with writing safe code than
with writing supposedly fast code. In order to do so I have a very
simple guideline on the subject:
Never return by reference unless you are returning either *this or an
argument you received by reference.
Those who preach otherwise should remember that the days of few
megahertz clocks and no cache are long gone for the vaste majority of
us.
|
Why is *this any safer than *this->member ?
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Motti Lanzkron Guest
|
Posted: Tue Jul 06, 2004 9:20 pm Post subject: Re: Const Reference Return Efficiency |
|
|
Nicola Musatti wrote:
| Quote: |
Never return by reference unless you are returning either *this or an
argument you received by reference.
|
I think that's a bit of an overstatement.
What's the difference between returning a member by ref and returning
*this? Both have the same life-span so the risk of dangling references
is the same. There are many legitimate reasons one would want to
return a reference to a member (even a const one), it could be
non-copyable for instance.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Joe Chen Guest
|
Posted: Wed Jul 07, 2004 7:58 am Post subject: Re: Const Reference Return Efficiency |
|
|
My apologies to Francis for accidentally hitting "reply" instead of "reply
group". Francis, please disregard the personal reply!
"Francis Glassborow" <francis (AT) robinton (DOT) demon.co.uk> wrote
| Quote: | Library implementors have to make careful judgement calls, and the
good ones get it right more often than not and go on learning from
experience.
|
Does this mean that encapsulation and abstraction are at odds with
efficiency and generic programming?
| Quote: | Now let me give you a direct counter example to your guideline.
Consider a class that has an std::vector member as a repository for a
certain type of data. Now how do I provide access to that data for
searching given that I do not know the general nature of the searches
that a user may wish to implement?
|
Isn't that the job that an iterator is designed to perform? What if the
implementor wanted to change the internal repository from a vector to a
list? I'm thinking of Meyer's EC++ #29, where it advises not to return
handles to internal data because it may make your library less flexible to
maintain, or may force changes on users when changes internal to the API are
made.
| Quote: | Copying a vector of unknown size can be so expensive as to completely
dominate the performance of an application. The class designer has no
way to know how expensive copying will be, only the user can know that.
|
Wouldn't that make it the user's decision on whether to use the correct API
for his purposes? How can a library implementor possibly predict all of the
circumstance his library can be used under?
If someone writes a set of APIs that return references (const or not) to
internal data members, then those lifetime couplings can easily spread
throughout all code that uses that API. In some cases, I would end up having
to make copies of those objects anyway in order to clean up my design. In
this case, the library implementor hasn't forseen that I don't need the
performance as much as I need the simplicity of design. So, again, it begs
the question of whether good OO design is at odds with efficiency.
And should efficiency always be considered before anything else?
Thanks!
Joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Guest
|
Posted: Wed Jul 07, 2004 5:20 pm Post subject: Re: Const Reference Return Efficiency |
|
|
| Quote: |
1. Since most modern compilers with do RVO on the getValue and
possibly eliminate the temporary, is avoiding the copy construction
on a return by value worth code that is encapsulation messy? I
feel uncomfortable revealing the internals of my class, or
introducting confusing lifetime symantics of the member variables
inside.
|
I understand your concern and somewhat agree with you. Returning
refernece to some implementation-specific inner object is a pain. And
returning by value in this case is obviously neater semantics-wise.
However, reality is cruel. RVO is not guaranteed to happen on every
compiler.
I suspect it will never be guaranteed.
And when we don't want to rely on RVO, it becomes a dilemma. Whether
we want safety and neat encapsulation or performance? I guess many
people prefer the latter. Faster, simple and the cost of safety and
encapsulation is quite affordable. After all, c++ is not an absolutely
safe language.
I'd say return-by-const-ref in this case is a sub-ideal but practical
solution.
| Quote: |
2. Will this prevent other compiler optimizations due to aliasing?
My suspicion is that since the compiler can never know how many
references to the internal representation there are, it is possible
the code is missing out on optimizations greater than what the
missing copy constructor provides.
|
Maybe not. Talking about aliasing, if getValue() is inlined,
obj.getValue() is no different than obj._value to the optimizer.
Storing reference or a pointer in an object may cause aliasing
problem, but not return-by-ref.
| Quote: |
3. Unless this is required by being in a large, tight loop and a
profiler deems it necessary, I feel that the cost of a copy construction
of the string if returned by value would be completely swamped by
other calculations done within a function and probably wouldn't
effect the overal profile. Therefore, it loses out on solid OO
encapsulation and flexibility at the cost of mistaken effciency.
|
Well. it depends on how your class is gonna be used. As Antoun pointed
out, If it is an open world (like a lib or a common module in a big
project), u really cannot predict if return-by-val can eventually
cause performance problem.
[ 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: Wed Jul 07, 2004 5:43 pm Post subject: Re: Const Reference Return Efficiency |
|
|
In article <wPGGc.22651$vO1.118294 (AT) nnrp1 (DOT) uunet.ca>, Joe Chen
<joe_w_chen (AT) hotmail (DOT) com> writes
| Quote: | My apologies to Francis for accidentally hitting "reply" instead of "reply
group". Francis, please disregard the personal reply!
|
No problem.
| Quote: |
"Francis Glassborow" <francis (AT) robinton (DOT) demon.co.uk> wrote in message
news:<pL3lsSQahp6AFwe$@robinton.demon.co.uk>...
Library implementors have to make careful judgement calls, and the
good ones get it right more often than not and go on learning from
experience.
Does this mean that encapsulation and abstraction are at odds with
efficiency and generic programming?
|
Sometimes, and again judgement is called for. That is one reason that
good library designers are paid (even if not always paid enough)
| Quote: |
Now let me give you a direct counter example to your guideline.
Consider a class that has an std::vector member as a repository for a
certain type of data. Now how do I provide access to that data for
searching given that I do not know the general nature of the searches
that a user may wish to implement?
Isn't that the job that an iterator is designed to perform? What if the
implementor wanted to change the internal repository from a vector to a
list? I'm thinking of Meyer's EC++ #29, where it advises not to return
handles to internal data because it may make your library less flexible to
maintain, or may force changes on users when changes internal to the API are
made.
|
Actually I look at it differently, once I have 'published' some internal
detail via a return type I have renounced the option to change that
detail unless I can do so without changing the public interface. To me
public interfaces are inviolate and may only be added to, never
subtracted from or modified (unless such modification continues to
provide all previous behaviour)
| Quote: |
Copying a vector of unknown size can be so expensive as to completely
dominate the performance of an application. The class designer has no
way to know how expensive copying will be, only the user can know that.
Wouldn't that make it the user's decision on whether to use the correct API
for his purposes? How can a library implementor possibly predict all of the
circumstance his library can be used under?
|
Exactly, s/he cannot and therefore should not pre-empt decisions best
left to the user. Return by const reference leaves the user the option
to copy and pay the costs of that. Return by value removes that choice
from the user so the library designer better have good reasons for
making that choice.
| Quote: | If someone writes a set of APIs that return references (const or not)
|
No, stick to the current discussion, returning a non-const reference is
conceptually a very different thing, one that is far more rarely
justifiable.
| Quote: | to
internal data members, then those lifetime couplings can easily spread
throughout all code that uses that API. In some cases, I would end up having
to make copies of those objects anyway in order to clean up my design. In
this case, the library implementor hasn't forseen that I don't need the
performance as much as I need the simplicity of design. So, again, it begs
the question of whether good OO design is at odds with efficiency.
|
Even with your assertions about good OO design, we are discussing C++
which allows (and even encourages) the use of other paradigms. Actually
it is very hard to see how return by value equates with good OO where
some would claim that there should be no such thing as a value
(interesting to contrast that with functional programming in which there
is, effectively, no such thing as an object)
| Quote: |
And should efficiency always be considered before anything else?
|
No, but nor should it not be considered. As always, this is a matter of
judgement. The problem with guidelines is that they are often used as a
substitute for judgement.
--
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 |
|
 |
|
|
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
|
|