POV-Ray : Newsgroups : povray.off-topic : C++ questions Server Time
7 Sep 2024 23:26:43 EDT (-0400)
  C++ questions (Message 111 to 120 of 123)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 3 Messages >>>
From: Invisible
Subject: Re: C++ questions
Date: 30 Sep 2008 05:49:19
Message: <48e1f61f$1@news.povray.org>
Hmm, so vectors seem to be able to do some pretty death-defying stuff! 
They're variable size, but they manage their memory automatically.

Now in a GC language, you can just pass anything anywhere. Usually in a 
language with manual memory management you have to be extremely careful 
about doing that.

However, vectors seem to make this surprisingly safe. Indeed, it appears 
that you can pass a vector in any way that you could pass something like 
an integer, and it will just do The Right Thing(tm). The only difference 
is that throwing a large vector around by value probably isn't a good idea.

Is that about right?

Here's another question: Suppose you have a function that's supposed to 
create a new vector and return it to the caller. What's the best way to 
do that?

Obviously the ideal thing to do would be to return a reference. However, 
if I create a vector in an auto variable, presumably when the function 
returns that variable will vanish, making the reference to it unusable. 
(If I'm understanding how this works.)

I guess if I return it by value the problem goes away. But that doesn't 
seem terribly efficient.

Maybe the thing to do would be to have the caller pass in a reference to 
an empty vector created outside?

Just trying to get my head round this stuff so I don't do anything dumb...


Post a reply to this message

From: Warp
Subject: Re: C++ questions
Date: 30 Sep 2008 11:37:29
Message: <48e247b9@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> Hmm, so vectors seem to be able to do some pretty death-defying stuff! 
> They're variable size, but they manage their memory automatically.

> Now in a GC language, you can just pass anything anywhere. Usually in a 
> language with manual memory management you have to be extremely careful 
> about doing that.

> However, vectors seem to make this surprisingly safe. Indeed, it appears 
> that you can pass a vector in any way that you could pass something like 
> an integer, and it will just do The Right Thing(tm). The only difference 
> is that throwing a large vector around by value probably isn't a good idea.

> Is that about right?

  That's the whole idea in C++ class design. If you write a class which is
not safe to use like that, then your design is bad.

  C++ classes have been designed to allow you to do that. As long as
you just create local instances of them and pass them by value (in other
words, as long as you don't use the keyword 'new' nor store pointers which
last longer than the object), if the class has been implemented properly
it's completely safe. (Ok, there are some exceptions, but basically.)

  It would be perfectly possible to implement a dynamic vector class which
has all the properties as std::vector, and which is efficient to pass by
value. The vector class could basically work like a reference-counted
handle to the array (in which case all the copies share the same array).
Or it could use the copy-on-write mechanism (in which case each copy has
its own array, but it's still very efficient to pass copies around).

  The reason why std::vector doesn't implement copy-on-write is that it
would add overhead to the []-indexing, which is usually something people
don't want. However, if you don't mind that overhead, or it's enough for
all the copies to share the same array, then you can implement your own
dynamic vector which uses reference counting and thus becomes much more
efficient to pass around by value.

  The nice thing about this is that whether copying the vector object
causes a deep-copy of the array, whether it's reference-counted, or
whether it uses copy-on-write, the interface doesn't change in any way.
In other words, the internal implementation is completely transparent and
its usage is exactly the same regardless.

> Here's another question: Suppose you have a function that's supposed to 
> create a new vector and return it to the caller. What's the best way to 
> do that?

> Obviously the ideal thing to do would be to return a reference. However, 
> if I create a vector in an auto variable, presumably when the function 
> returns that variable will vanish, making the reference to it unusable. 
> (If I'm understanding how this works.)

> I guess if I return it by value the problem goes away. But that doesn't 
> seem terribly efficient.

  Actually if you have a function like:

    std::vector<int> createVector(whatever) { ... }

and then call it like:

    std::vector<int> myVector = createVector(whatever);

the compiler will most probably be able to optimize the copying away.
Basically the 'createVector()' function will build its return value right
onto that 'myVector' variable (rather than building a local copy which it
then returns by value).

  Of course there are limits to this. For example, if you have something
like this:

    std::vector<int> myVector;
    // ...some code using myVector here...
    myVector = createVector(whatever);

then the compiler has no choice: It must build the return value of
'createVector()' into a temporary and then copy it to 'myVector'.

  One common idiom is for the function to take the vector as reference:

    void createVector(whatever, std::vector<int>& result) { ... }

and then you give your vector as parameter, and the function will then
add the data to it.

  Btw, there's a trick to avoid the copying of that temporary in the first
case:

    std::vector<int> myVector;
    // ...some code using myVector here...
    std::vector<int> tempVector = createVector(whatever);
    myVector.swap(tempVector);

  What this does is that the result of 'createVector' is built onto
'tempVector', and then its contents swapped with 'myVector'. Swapping of
vectors is an O(1) operation and avoids the needless copying.)

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: C++ questions
Date: 30 Sep 2008 11:50:55
Message: <48e24adf$1@news.povray.org>
>> Is that about right?
> 
>   That's the whole idea in C++ class design. If you write a class which is
> not safe to use like that, then your design is bad.
> 
>   C++ classes have been designed to allow you to do that. As long as
> you just create local instances of them and pass them by value (in other
> words, as long as you don't use the keyword 'new' nor store pointers which
> last longer than the object), if the class has been implemented properly
> it's completely safe. (Ok, there are some exceptions, but basically.)

That's certainly a big step up from C, where as soon as you touch 
something that's dynamically allocated, basically your program is almost 
guaranteed to segfault. But then, C doesn't provide any way for a 
library designer to control what happens with their stuff at the 
caller's end. That's very machine efficient, but not terribly safe...

>   The nice thing about this is that whether copying the vector object
> causes a deep-copy of the array, whether it's reference-counted, or
> whether it uses copy-on-write, the interface doesn't change in any way.
> In other words, the internal implementation is completely transparent and
> its usage is exactly the same regardless.

That's a good property.

>> Here's another question: Suppose you have a function that's supposed to 
>> create a new vector and return it to the caller. What's the best way to 
>> do that?
> 
>   One common idiom is for the function to take the vector as reference:
> 
>     void createVector(whatever, std::vector<int>& result) { ... }
> 
> and then you give your vector as parameter, and the function will then
> add the data to it.

That seems like the simplest thing to do then. The allocation and 
lifetime of the object is quite obvious by looking at the caller, and 
it's simple to implement at the called end.


Post a reply to this message

From: Warp
Subject: Re: C++ questions
Date: 30 Sep 2008 11:55:51
Message: <48e24c07@news.povray.org>
Warp <war### [at] tagpovrayorg> wrote:
>   Actually if you have a function like:

>     std::vector<int> createVector(whatever) { ... }

> and then call it like:

>     std::vector<int> myVector = createVector(whatever);

> the compiler will most probably be able to optimize the copying away.

  Oh, and I forgot to say: The compiler doesn't even need to see the
implementation of 'createVector()' in order to do this optimization.
In other words, the compiler doesn't require to be able to inline that
function to do the optimization. The implementation of that function
could be in another compilation unit, or it could even be in a
precompiled library.

-- 
                                                          - Warp


Post a reply to this message

From: Mueen Nawaz
Subject: Re: C++ questions
Date: 30 Sep 2008 13:46:06
Message: <48e265de$1@news.povray.org>
Invisible wrote:
> Hmm, so vectors seem to be able to do some pretty death-defying stuff!
> They're variable size, but they manage their memory automatically.

	And they let you go out of bounds, too!


-- 
Vultures only fly with carrion luggage.


                    /\  /\               /\  /
                   /  \/  \ u e e n     /  \/  a w a z
                       >>>>>>mue### [at] nawazorg<<<<<<
                                   anl


Post a reply to this message

From: Warp
Subject: Re: C++ questions
Date: 30 Sep 2008 16:31:55
Message: <48e28cbb@news.povray.org>
Mueen Nawaz <m.n### [at] ieeeorg> wrote:
> Invisible wrote:
> > Hmm, so vectors seem to be able to do some pretty death-defying stuff!
> > They're variable size, but they manage their memory automatically.

>         And they let you go out of bounds, too!

  Well, you could use the at() member function if you want it to perform
bounds checks.

-- 
                                                          - Warp


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: C++ questions
Date: 30 Sep 2008 20:59:44
Message: <48e2cb80@news.povray.org>
Mike Raiford wrote:
> "C allows you to shoot yourself in the foot. C++ allows you to shoot
> yourself in the foot and reuse the bullet"

I remember it differently.

"C makes it easy to shoot yourself in the foot. C++ makes it harder, but
when you do it blows the whole leg off."


Post a reply to this message

From: Mueen Nawaz
Subject: Re: C++ questions
Date: 30 Sep 2008 21:36:30
Message: <48e2d41e$1@news.povray.org>
Warp wrote:
> Mueen Nawaz <m.n### [at] ieeeorg> wrote:
>> Invisible wrote:
>>> Hmm, so vectors seem to be able to do some pretty death-defying stuff!
>>> They're variable size, but they manage their memory automatically.
> 
>>         And they let you go out of bounds, too!
> 
>   Well, you could use the at() member function if you want it to perform
> bounds checks.

	Well, if we're dealing with vectors, why not just check its size? Is at
more efficient?

	Anyway, I wasn't complaining - I just wanted to make sure he knew that
in C++, nothing stops you from going out of bounds (probably to maintain
efficiency of lookups). Many other popular languages will die if you try
that.

-- 
When you die, you lose a very important part of your life.
                -- Brooke Shields


                    /\  /\               /\  /
                   /  \/  \ u e e n     /  \/  a w a z
                       >>>>>>mue### [at] nawazorg<<<<<<
                                   anl


Post a reply to this message

From: Warp
Subject: Re: C++ questions
Date: 1 Oct 2008 09:19:46
Message: <48e378f2@news.povray.org>
Nicolas Alvarez <nic### [at] gmailcom> wrote:
> "C makes it easy to shoot yourself in the foot. C++ makes it harder, but
> when you do it blows the whole leg off."

  I honestly don't understand what that is trying to say. I have no
experience (either personal or indirect) in C++ bugs being more severe
than C bugs.

-- 
                                                          - Warp


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: C++ questions
Date: 1 Oct 2008 13:58:47
Message: <48e3ba56@news.povray.org>
Warp wrote:
>   I honestly don't understand what that is trying to say. I have no
> experience (either personal or indirect) in C++ bugs being more severe
> than C bugs.
> 

"C makes it easy to shoot yourself in the foot; C++ makes it harder, but
when you do it blows your whole leg off".

"Yes, I said something like that (in 1986 or so). What people tend to miss,
is that what I said there about C++ is to a varying extent true for all
powerful languages. As you protect people from simple dangers, they get
themselves into new and less obvious problems. Someone who avoids the
simple problems may simply be heading for a not-so-simple one. One problem
with very supporting and protective environments is that the hard problems
may be discovered too late or be too hard to remedy once discovered. Also,
a rare problem is harder to find than a frequent one because you don't
suspect it."

from Bjarne Stroustrup's C++ FAQ.


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 3 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.