Dynamically choosing what to "new"

J

JohnQ

Pat said:
Interesting thread... The efficiency of the "GetName()" method wasn't
really a concern, because it was just a function I made up to illustrate
my
problem.

But in response to the comments about passing by addres vs passing by
reference vs passing by value, I really don't understand the arguments
against passing pointers as a parameter.

I don't either. Passing a pointer is fine, but you'll probably have to do
precondition checking for null with a pointer while for a reference that is
eliminated because references cannot be null. (I wonder if the standard will
eventually incorporate null references?).
It's guaranteed to be fast,
without requiring tricky compiler optimizations. And if you do it as a
rule, you don't really have a problem with it "adding complexity."

But complexity issues aside (I don't really see what they are, anyway), as
I initially said, in "real world" functions, I don't see a way around
passing pointers. If you've got a function that takes several large
objects as parameters, accesses various members of each, then returns some
value as a result, I think you'd be crazy to pass in the objects as
copies.

Agreed, but references were created for that very scenario I think. Nothing
wrong with pointers though either.
I've really never given it much thought. It has just been an accepted
rule
of thumb at places where I've worked -- mainly game development, where
performance is crucial.

I'm willing to believe that a smart compiler might be able to optimize
pass-by-value to be *as good* as pass-by-reference, in some cases, but I
don't really see what you gain, besides maybe a longer compile time.

I don't think most will make a case for passing object instances by value.

John
 
G

Gianni Mariani

JohnQ said:
I know, that's why I posted: it's incorrect.
Debatable.


Oh, I thought it was whether COW is worthwhile or not.

COW is an optimization. It may or may nor be worthwhile, like all
optimizations it depends.
 
G

Greg Herlihy

I don't either. Passing a pointer is fine, but you'll probably have to do
precondition checking for null with a pointer while for a reference that is
eliminated because references cannot be null. (I wonder if the standard will
eventually incorporate null references?).

The argument is against passing any parameter at all to a routine that needs
no input. In particular a class object's GetName() method requires no data
from the callee in order to return the object's name, and therefore has no
reason to accept a parameter.

But the unneeded parameter does add complexity - which you may not mind -
but what about other programmers who might be responsible for maintaining
this code in the future? Are they likely to welcome anything that makes this
code (which after all they did not write and are not familiar with) any more
difficult to understand?

The added complexity is simple to identify: there is a function that should
not need a parameter - but that requires one nonetheless. So, before writing
code to call this method, the programmer has to figure out what this
mysterious parameter does - and how to use it in ways that will satisfy the
function's preconditions. And all of this work (and the opportunities for
mistakes it creates) provides no benefit that might justify these costs.
Agreed, but references were created for that very scenario I think. Nothing
wrong with pointers though either.

There are numerous reasons to avoid pointers as I/O parameters. For one, a
pointer might be NULL - a possibility that the caller or callee may not be
prepared to handle. Pointers are also likely raise issues of allocation and
deallocation as well as object lifetimes - all issues that may be difficult
to coordinate and debug.
I don't think most will make a case for passing object instances by value.

Clearly whenever the object instance itself is the same size or smaller than
a pointer or a reference to that object would be - it makes sense to pass
the object by value. Pointers themselves are an obvious example of this
principle. Passing a pointer to a pointer (or a pointer by const reference)
for efficiency reasons would make little sense - since it is clear in the
case of a pointer object that no additional efficiency will be attained by
any calling convention other than passing the pointer by value.

And what holds for a pointer type also applies equally as well to any object
the same size or smaller than a pointer - built-in integral types for
example usually fall into this category. In fact passing a short by
reference or pointer is much more likely to be less efficient than passing
the short by value. In fact, boost even has a library "call_traits" that
pretty much automates the selection of a parameter's calling convention for
optimal efficiency based on its type.

Greg
 
J

JohnQ

Greg Herlihy said:
The argument is against passing any parameter at all to a routine that
needs
no input.

No, I don't think that is the topic at all, though I did bring up that
design issue in a previous post in this thread. The OP was just asking in
general about objects passed to a function and why "pointers to such are
bad".
There are numerous reasons to avoid pointers as I/O parameters. For one, a
pointer might be NULL

That's been mentioned in a prior post (by me).
- a possibility that the caller or callee may not be
prepared to handle. Pointers are also likely raise issues of allocation
and
deallocation as well as object lifetimes - all issues that may be
difficult
to coordinate and debug.

The issue is the cost of copying objects if they are passed in by value.
Which naturally leads in to a discussion about copy-on-write.
Clearly whenever the object instance itself is the same size or smaller
than
a pointer or a reference to that object would be - it makes sense to pass
the object by value.

That's been noted already by the OP. The "understood" theme was the passing
of objects (or at least I certainly would not assume that posters here are
in the first day of programming class! Geez.). You really should read all
the prior posts in a thread before you jump in the middle of one and rehash
that which has already been put forth.

John
 
G

Greg Herlihy

I know, that's why I posted: it's incorrect.

No - since both the C++ compiler and the Standard Library belong to
the "implementation" it could be possible for a C++ compiler to
"implement" the Standard Library by, say, emitting appropriate machine
code whenever it compiles user code that makes use of the Standard
Library's facilities. In short, there is no requirement that the
Standard C++ Library be written in C++ or even that it exist as a code
"library" at all. So while it may seem odd to think of the STL and the
C++ compiler as two sides of the same code - essentially they are.

Greg
 
J

JohnQ

Greg Herlihy said:
No - since both the C++ compiler and the Standard Library belong to
the "implementation" it could be possible for a C++ compiler to
"implement" the Standard Library by, say, emitting appropriate machine
code whenever it compiles user code that makes use of the Standard
Library's facilities. In short, there is no requirement that the
Standard C++ Library be written in C++ or even that it exist as a code
"library" at all. So while it may seem odd to think of the STL and the
C++ compiler as two sides of the same code - essentially they are.

I'm not buying it. A freestanding implementation need not supply library
functionality at all, so it's optional. Standard Template LIBRARY. Until it
becomes common practice to embed STL functionality into compilers, I say
calling STL a part of the compiler is incorrect. Part of the language spec,
yes. Part of any known compiler, no.

John
 
J

James Kanze

I know, that's why I posted: it's incorrect.

In what sense? As far as the standard is concerned, the
standard library is part of the language. You get it with the
compiler, and use it as if it were part of the compiler. The
compiler is aware of certain parts of it, at least (e.g.
type_info, or operator new()). Most implementations do allow
replacing a significant part, at least if it is done as a block,
but that's an extension, and you normally think of the standard
library (plus a number of system libraries, such as the Posix
interface) as being part of the "implementation", in other
words, the compiler. You don't worry about how
std::basic_string is implemented, you just use it.
 
J

James Kanze

[...]
I can't think of any situation where passing a string by
pointer would be the preferred solution.

When it's optional, and you want to allow for a null pointer in
the case where it isn't provided:).

There are, in fact, a number of different conventions as to when
to use pointers, and when to use references. At one extreme,
there are people who practically never use non-const references;
if the object is to be modified by the function, they want this
immediately visible at the call site (and thus require that the
caller explicitly take the address). At the other, a lot of
people use references except when it is impossible (e.g. because
they also need a null pointer). In between, I've encountered
more than a few places where the rule was to use a pointer if
the function did anything "pointer-like" with it; basically, if
it deleted the object, or stored the address somewhere for later
use.

What I've not seen very often is using a pointer for a pure out
parameter; generally, a return value is to be preferred. Most
of the time, inout uses a reference, although as mentionned
above, there are people who disagree. And everywhere I've seen,
pure in parameters are by value or by const reference, unless
they're optional, and a null pointer is used to indicate their
absense.
 
J

James Kanze

On Jun 12, 1:37 am, "JohnQ" <[email protected]>
wrote:

[...]
I don't think most will make a case for passing object
instances by value.

The standard library does it all the time: iterators,
predicates, comparison operators...

John Potter once made the (valid) argument that passing by const
reference, instead of passing by value, is an optimization, and
as such, should only be used when the profiler says it is
necessary. I think that most people are a little less rigorous
about it than that, and will accept pass by const reference if
the object is potentially expensive to copy (in the sense that
it has, for example, an open size, and so must involve dynamic
allocation, for example). In practice, I'd consider it an
acceptable rule to pass containers by const reference, and
everything else by value.

This only applies, of course, to in parameters. In general, it
is desirable to use only in parameters, and to have at most a
single out parameter, which is returned by value as a return
value. But this isn't always pratical; sometimes, you need two
out parameters, or an inout (rather than separate in and out
parameters); in such cases, non-const references are the most
generally approved solution (although some people prefer
pointers, making the fact that the function modifies the object
explicit at the call site).

The problem with using references or pointers for out
parameters, of course, is that the client code must declare (and
construct, if the object has class type) an instance at the call
site, before he has anything to put in it. If getS() is a
function which returns a string (has a single out parameter),
something like:
std::string result ;
getS( result ) ;
is a lot more painful than just:
std::string result( getS() ) ;
Depending on the implementation, it's likely to be slower as
well.
 
J

JohnQ

I know, that's why I posted: it's incorrect.

"In what sense? As far as the standard is concerned, the
standard library is part of the language. You get it with the
compiler, and use it as if it were part of the compiler. The
compiler is aware of certain parts of it, at least (e.g.
type_info, or operator new()). Most implementations do allow
replacing a significant part, at least if it is done as a block,
but that's an extension, and you normally think of the standard
library (plus a number of system libraries, such as the Posix
interface) as being part of the "implementation", in other
words, the compiler. You don't worry about how
std::basic_string is implemented, you just use it."

Correction: that is how YOU perceive it. I don't even think of a vendor's
combination as an entity: I may use JohnQ Templates rather than the STL that
comes with it. When someone say's "compiler", I indeed think the executable
that does the compiling of source code into machine code or assembly. In the
other case, I'd use "development environment", VC++ or similar terminology.

John
 
G

Gavin Deane

"In what sense? As far as the standard is concerned, the
standard library is part of the language. You get it with the
compiler, and use it as if it were part of the compiler. The
compiler is aware of certain parts of it, at least (e.g.
type_info, or operator new()). Most implementations do allow
replacing a significant part, at least if it is done as a block,
but that's an extension, and you normally think of the standard
library (plus a number of system libraries, such as the Posix
interface) as being part of the "implementation", in other
words, the compiler. You don't worry about how
std::basic_string is implemented, you just use it."

Correction: that is how YOU perceive it. I don't even think of a vendor's
combination as an entity: I may use JohnQ Templates rather than the STL that
comes with it. When someone say's "compiler", I indeed think the executable
that does the compiling of source code into machine code or assembly. In the
other case, I'd use "development environment", VC++ or similar terminology.

I don't think "development environment" is the right term. To many
people that will imply additional concepts like debuggers and other
tools that are beyond the scope of the C++ standard and I don't think
that's what the posts you are responding to were talking about at all.

The concept being discussed is the implementation of all the
requirements of ISO standard number 14882 (whatever the precise title
of the document is) and nothing else. That's a well defined and easily
understood concept. To be able to refer to that concept in
conversation, it is useful to give it a name - my preference is to
call it "the implementation". I happen to be used to implementations
of ISO 14882 that are provided in two basic parts: 1) an executable
that turns source code into machine code and 2) files of source code
that implement the standard library parts of ISO 14882. And I happen
to be used to the first part (the executable) being called a compiler.
So to also use the name "compiler" to refer to the concept of the
whole implementation of ISO 14882 (the sum of parts 1 and 2 above)
sits slightly uncomfortably with me because using the same word to
mean two different things is generally a bad idea.

However, I recognise that my discomfort only comes about through my
knowledge of *how* the requirements of ISO 14882 have been implemented
in the implementations I am used to (two separate parts as above). And
since the existence of two separate parts is an implementation detail,
as an engineer I should be ready and able to ignore it. So if other
peple are happy to use "compiler" as the name for the concept that I
prefer to call "implementation" that's fine by me because I know
exactly what they are talking about.

But the important thing is to all be talking about the same thing and
I think the concept is clear even if the name for it is contentious.

Gavin Deane
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message
On Jun 12, 1:29 am, "JohnQ" <[email protected]>
wrote:
"In what sense? As far as the standard is concerned, the
standard library is part of the language. You get it with the
compiler, and use it as if it were part of the compiler. The
compiler is aware of certain parts of it, at least (e.g.
type_info, or operator new()). Most implementations do allow
replacing a significant part, at least if it is done as a block,
but that's an extension, and you normally think of the standard
library (plus a number of system libraries, such as the Posix
interface) as being part of the "implementation", in other
words, the compiler. You don't worry about how
std::basic_string is implemented, you just use it."
Correction: that is how YOU perceive it.

Correction: it's how the language is defined. Every language
I've ever used is defined in this way.
I don't even think of a vendor's combination as an entity: I
may use JohnQ Templates rather than the STL that comes with
it.

No you may not. If it works, it's an extension on the part of
the compiler. And it doesn't always work.
When someone say's "compiler", I indeed think the executable
that does the compiling of source code into machine code or
assembly. In the other case, I'd use "development
environment", VC++ or similar terminology.

That's a more or less frequent distinction. We speak of
compilers, linkers, library components, etc. to refer to parts
of the implementation. But the implementation is a monolith;
you can't mix and match different parts. And the distinctions
are blurred; most systems today will generate code at link time,
given certain options, and there is a definition interaction
between the library and the language in certain cases, such as
std::type_info. In the past, C compilers regularly "knew" the
semantics of certain standard functions (and generated them
inline), and it's to be expected that in the future, C++
compilers will know the details things like std::vector.

The standard is very clear about this. There's really no room
for discussion.
 
J

JohnQ

"James Kanze" <[email protected]> wrote in message
On Jun 12, 1:29 am, "JohnQ" <[email protected]>
wrote:
"In what sense? As far as the standard is concerned, the
standard library is part of the language. You get it with the
compiler, and use it as if it were part of the compiler. The
compiler is aware of certain parts of it, at least (e.g.
type_info, or operator new()). Most implementations do allow
replacing a significant part, at least if it is done as a block,
but that's an extension, and you normally think of the standard
library (plus a number of system libraries, such as the Posix
interface) as being part of the "implementation", in other
words, the compiler. You don't worry about how
std::basic_string is implemented, you just use it."
Correction: that is how YOU perceive it.

"Correction: it's how the language is defined. Every language
I've ever used is defined in this way."

I'm not big on other people's definitions (especially when they're wrong!).
Hehe. I hear what you're saying though. When I switched from Borland to MS I
switched to using the MS libraries also because they are tied to the vendors
compiler. I haven't noticed anything in the other direction though. That
would be a serious matter (there should be a warning on the box or
something).

Whether I can get away from using all of the standard headers/libraries or
not is yet to be determined. I think it's a worthwhile pursuit though.
Moreso now after the info you presented.
I don't even think of a vendor's combination as an entity: I
may use JohnQ Templates rather than the STL that comes with
it.

"No you may not. If it works, it's an extension on the part of
the compiler. And it doesn't always work."

Yes I may, and I do. Honestly, I'm hardly worried about being
standard-compliant. Indeed, that's like being put in a straitjacket.
When someone say's "compiler", I indeed think the executable
that does the compiling of source code into machine code or
assembly. In the other case, I'd use "development
environment", VC++ or similar terminology.

"That's a more or less frequent distinction. We speak of
compilers, linkers, library components, etc. to refer to parts
of the implementation. But the implementation is a monolith;
you can't mix and match different parts. And the distinctions
are blurred; most systems today will generate code at link time,
given certain options, and there is a definition interaction
between the library and the language in certain cases, such as
std::type_info. In the past, C compilers regularly "knew" the
semantics of certain standard functions (and generated them
inline), and it's to be expected that in the future, C++
compilers will know the details things like std::vector.

The standard is very clear about this. There's really no room
for discussion."

A very good reason to get away from the std libraries and "lock you in"
implementations. (That new fangled language is looking better all the
time!).

John
 
G

Gavin Deane

Yes I may, and I do. Honestly, I'm hardly worried about being
standard-compliant. Indeed, that's like being put in a straitjacket.

That is of course entirely up to you. But if that's your approach, why
are you posting in a newsgroup whose purpose is deliberately and
explicitly restricted to only standard-compliant C++, the complete
opposite of what you are concerned with?

You aren't surprised by everyone else here being extremely concerned
with standard-compliance are you?

Gavin Deane
 
J

JohnQ

Gavin Deane said:
That is of course entirely up to you. But if that's your approach, why
are you posting in a newsgroup whose purpose is deliberately and
explicitly restricted to only standard-compliant C++, the complete
opposite of what you are concerned with?

You aren't surprised by everyone else here being extremely concerned
with standard-compliance are you?

Don't be an extremist.

John
 
T

terminator

Yes, passing a pointer is more efficient because it avoids copying the
entire object onto the stack. I try to always pass pointers or references,
unless the parameter is small (e.g. int). In this one simplified case it
might not make much difference, since the "=" operator is going to
basically perform a copy anyway. But for real world functions, it's a good
idea.

const char* Dog::GetName()
{
static const char* const s = "Dog";
return s;
};

how is this going to be expensive?Is it cost more than the size of a
pointer on stack?

regards,
FM.
 
T

Thomas J. Gritzan

terminator wrote:
[...about passing pointers to functions instead of values...]
const char* Dog::GetName()
{
static const char* const s = "Dog";
return s;
};

how is this going to be expensive?Is it cost more than the size of a
pointer on stack?

You don't need the static pointer:

const char* Dog::GetName()
{
return "Dog";
};

This works as well, since string literals live as long as the program runs.

And this is not expensive. The Foreposter talked about passing bigger
objects (like std::string), where copying is more expensive, so passing
them by reference makes sense:

void someFunction(const std::string& someString);

But for returning such objects, it is more expressive to return them
directly instead of passing a non-const reference or a pointer:

std::string someFunction();
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top