Quick question on smart pointers

R

Richard Herring

Torsten Mueller said:
Yes, of course!


I do not. That's the difference.

Sorry, perhaps I've just seen too many young programmers becoming
frustrated because of a serious memory problem in their own absolutely
safe smart pointer world, because they (or anybody else!) forgot
somewhere to use a smart pointer where he should use one and then they
soon begin to blame C++ for causing daylong debugging sessions in
their safe programs.

So what you're saying is this:

Some student programmers have problems because they misuse (or
occasionally fail to use?) smart pointers. Therefore we should not use
smart pointers.

Did I get that right?

OTOH I've seen too many young programmers becoming frustrated because of
a serious memory problem in their C-shaped world, because they used raw
pointers without first designing an ownership model.

The cure for "forgetting somewhere to use a smart pointer" is not to
abandon smart pointers but to start with an ownership model, and then
enforce it by using factories etc. and make it impossible to expose raw
pointers at all (a quick search for all instances of "get()", "this",
"new", "delete" etc. should find most of the abuses).
 
T

Torsten Mueller

Richard Herring said:
So what you're saying is this:

Some student programmers have problems because they misuse (or
occasionally fail to use?) smart pointers. Therefore we should not
use smart pointers.

Did I get that right?

OTOH I've seen too many young programmers becoming frustrated because
of a serious memory problem in their C-shaped world, because they
used raw pointers without first designing an ownership model.

The problem of smart pointers is that they cause a feeling of safety,
and this feeling is thin ice. "Our program is safe - we always use
smart pointers. And so we have completely safe code. If something is
wrong it can't be our code - we are safe!" ... I heard this just a few
times too often. I have done endless debugging sessions in code of
other people who were not able to understand their own code but beeing
very sure it's safe ... Even explaining them the problem is a problem
itself. This feeling of false safety does not exist in the classic
style. And in my opinion this is indeed an advantage.

What I want to say is, everyone should use the things he understands
completely. If anyone understands how smart pointers work and if he
can be sure all the others in his team understand this as well, they
may use them. No problem! I have never seen a real reason for using
smart pointers. This is my opinion. But the question came from a
beginner. And I oftenly found, people who do not understand raw
pointers have also serious problems using smart pointers, at least
when calling system or API functions.

T.M.
 
R

Richard Herring

Torsten Mueller said:
The problem of smart pointers is that they cause a feeling of safety,
and this feeling is thin ice. "Our program is safe - we always use
smart pointers. And so we have completely safe code. If something is
wrong it can't be our code - we are safe!"

Then you have an education problem, not a smart-pointers problem.

Of course smart pointers don't guarantee safety. Smart pointers plus the
supporting concepts of factory patterns etc.) are just a part of a
well-defined ownership model. It's the latter which makes safe programs.
... I heard this just a few
times too often. I have done endless debugging sessions in code of
other people who were not able to understand their own code but beeing
very sure it's safe ... Even explaining them the problem is a problem
itself. This feeling of false safety does not exist in the classic
style. And in my opinion this is indeed an advantage.

So we should all deliberately use unsafe raw pointers to write fragile
code, just because it doesn't feel safe? Is that what they call "extreme
programming"? ;-)
What I want to say is, everyone should use the things he understands
completely. If anyone understands how smart pointers work and if he
can be sure all the others in his team understand this as well, they
may use them. No problem! I have never seen a real reason for using
smart pointers.

You've never seen an example of smart pointers removing the need for
putting try-catch blocks around multiple memory allocations? Never seen
an example of RAII? Never even seen a mismatched new and delete?
This is my opinion.
Indeed.

But the question came from a
beginner. And I oftenly found, people who do not understand raw
pointers have also serious problems using smart pointers, at least
when calling system or API functions.

Sure. But "what beginners don't understand" is no basis for deciding
what concepts to use to write reliable programs.
 
T

Torsten Mueller

Richard Herring said:
So we should all deliberately use unsafe raw pointers to write
fragile code, just because it doesn't feel safe?

But it's just not true that raw pointers are unsafe. You just should
know what your're doing. And this is how I understand my job.
You've never seen an example of smart pointers removing the need for
putting try-catch blocks around multiple memory allocations?

No, never. What should the try-catch-block do in this case? What
exception should be caught? bad_alloc? I would rather search for the
reason of the exception and I would find it definitely.
Never seen an example of RAII?

Is this something smart pointers are really necessary for?
Never even seen a mismatched new and delete?

Sure I have. But I can count such situations on just one hand. It's a
question of personal experience handling these things. It's not even
difficult, it's just a bit handwork.

T.M.
 
R

Richard Herring

Torsten Mueller said:
But it's just not true that raw pointers are unsafe.

It's more true than that smart pointers are.
You just should
know what your're doing. And this is how I understand my job.

Sure, but even Homer nods. Why make things difficult for yourself?
No, never.

Then you can't be reading this thread very carefully. Bart Kowalski
posted an example in
What should the try-catch-block do in this case?

I don't know what it "should" do since I'm arguing that it's not
necessary when you use smart pointers properly. What it does in the
usual example is to mop up half-allocated resources and rethrow.
What
exception should be caught?

Everything that might break an invariant (i.e. leave the object in an
inconsistent state.)
bad_alloc?

Much more. Anything that might happen while the invariant isn't
satisfied.
I would rather search for the
reason of the exception and I would find it definitely.

You're missing the point. The problem is not in detecting the exception,
but in clearing up after it.
Is this something smart pointers are really necessary for?

Nothing is necessary. You could just write C. But since memory is an
obvious example of a resource, they are an excellent example of it.
Sure I have. But I can count such situations on just one hand.

Even in other people/s code, like those young programmers who spend all
their time becoming frustrated because of a serious memory problem?
It's a
question of personal experience handling these things. It's not even
difficult, it's just a bit handwork.

The same is true of smart pointers, but the workload is even less, as
there are no deletes to be matched.
 
P

Panjandrum

Torsten said:
But it's just not true that raw pointers are unsafe. You just should
know what your're doing. And this is how I understand my job.

Right! And also it's just not true that 'smart pointers' are smart.
Actually they are a very crude way to handle resources.
 
T

Torsten Mueller

Panjandrum said:
Right! And also it's just not true that 'smart pointers' are smart.
Actually they are a very crude way to handle resources.

Nobody talks about resources. Resources are just there.

Smart pointer protagonists tend to use smart pointers always and
everywhere. This means they oftenly avoid to use simple local objects
on the stack. They allocate them on the heap rather because "all
objects need a safe smart pointer around". (This is oftenly
inconsequent - they put always std::string and std::vector objects on
the stack but self-made objects belong surely on the heap ...)

The problem is not only the allocation and deallocation time the heap
management and the OS well need but also that these millions of
temporary heap objects fragment the heap enormously. (This effect
differs from compiler to compiler.) Analyzing this in a given
application with a mysterious high memory usage I found situations
where more than 40% of the memory the heap management had requested
from the OS was not used anymore. This memory was allocated for just
small temporary objects and could not been released because of
fragmentation.

Indeed I use much more local objects directly on the stack. The stack
is is allocated just once and it gets never fragmented. I also try to
use real member variables in classes rather than pointers to heap
objects. That's why I can avoid these situations of partly initialized
objects in most cases. I never throw exceptions from constructors.

T.M.
 
R

Richard Herring

Torsten Mueller said:
Nobody talks about resources. Resources are just there.

RAII is a common topic of conversation in these parts.
Smart pointer protagonists tend to use smart pointers always and
everywhere. This means they oftenly avoid to use simple local objects
on the stack. They allocate them on the heap rather because "all
objects need a safe smart pointer around".

You must work with some very strange people. *Informed* smart-pointer
protagonists do nothing of the sort. Since they have a well-defined
ownership model they know exactly where to use smart pointers, and that
certainly isn't for objects with local scope.

What they avoid altogether is the unsafe use of raw pointers.
(This is oftenly
inconsequent - they put always std::string and std::vector objects on
the stack but self-made objects belong surely on the heap ...)

The problem is not only the allocation and deallocation time the heap
management and the OS well need but also that these millions of
temporary heap objects fragment the heap enormously. (This effect
differs from compiler to compiler.) Analyzing this in a given
application with a mysterious high memory usage I found situations
where more than 40% of the memory the heap management had requested
from the OS was not used anymore. This memory was allocated for just
small temporary objects and could not been released because of
fragmentation.

Something wrong with the memory management code? If objects are
released precisely in reverse order of allocation (as will be the
pattern if you use smart pointers with local scope) I'd have thought
fragmentation would be unlikely.
Indeed I use much more local objects directly on the stack. The stack
is is allocated just once and it gets never fragmented. I also try to
use real member variables in classes rather than pointers to heap
objects. That's why I can avoid these situations of partly initialized
objects in most cases. I never throw exceptions from constructors.

Can you guarantee that the constructors of your "real member variables"
also never throw?
 

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

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top