Are these really the basics of programming in C++ with visual studio 2008?

Pages: 1234
closed account (4z0M4iN6)
Yes, the pointers are copied. What they point to is not copied. So if the destructor of the temporary uses delete, Object5 will be left with a dangling pointer. That's exactly the issue with shallow vs deep copying.


Yes so it is and ecactly this is the bug: "The destructor of the temporary must not be called."

And what will you do with a deep copy?. There is nothing to copy! Or the deep copy operator should allocate the same amount of memory a second time with the same result?
Last edited on
"The destructor of the temporary must not be called."

Yes, it must. Everything that is created must be destroyed. In the case of a temporary object, it is destroyed at the end of the expression it appears in. The following line:
Object5 = CompilerTest("UsedObject");
Creates a nameless, temporary object of type CompilerTest, calls operator= on Object5 with the temporary object as the parameter and then the temporary object is destroyed (and that always involves calling its destructor).

There is nothing to copy!

If the class has no members, then yes, there's nothing to copy. But then there would be no problem.
Last edited on
closed account (4z0M4iN6)
There is nothing to copy!

Sorry, there is nothing to deep copy (only the pointer)

1
2
3
Yes, it must. Everything that is created must be destroyed. In the case of a temporary object, it is destroyed at the end of the expression it appears in. The following line:
Object5 = CompilerTest("UsedObject");
Creates a nameless, temporary object of type CompilerTest, calls operator= on Object5 with the temporary object as the parameter and then the temorary object is destroyed.


Really? And what about this:

CatClass CatFrisky = CatClass("Frisky");

If you argument so: Why don't they destroy the new object in this case?

Yes are right about: the temporary object has to be destroyed.

But with free and not with delete, if the object is used.
Last edited on
CatClass CatFrisky = CatClass("Frisky");

This is one of the special cases where the C++ standard allows the compiler to perform copy elision, so the compiler may generate code that is equivalent to:
CatClass CatFrisky("Frisky");

But with free and not with delete

What? No. Destroying an object always involves calling the destructor.

if the object is used.

Read my previous post again, or elaborate on what you mean by "used".
closed account (4z0M4iN6)
What? No. Destroying an object always involves calling the destructor.


Why? Ok the final destruction involves calling the destructor, but not a temporary intermediate step, which only was performed, because the compiler developers didn't make the optimal implementation.


Read my previous post again, or elaborate on what you mean by "used"


If it's an assignment.

There shouldn't be much difference between:

int a = 5;

and

int a;
a = 5;

We don't expect, that the object would be destructed.

And an assignment also is such a special case.

The intermediate step only was neccessary, because the compiler developers were too lazy to implement something like:

MyCat.CatClass("Frisky");

I know, it's not the correct C++ syntax. But the compiler could do this.



closed account (zb0S216C)
dadbe wrote:
"There shouldn't be much difference between:

int a = 5;

and

int a;
a = 5;"

The first is initialisation which calls the constructor (if it's a class), while the second is an assignment which calls the assignment operator. The two are different.

dadabe wrote:
"because the compiler developers were too lazy to implement something like:

MyCat.CatClass("Frisky");"
dadabe wrote:
"But the compiler could do this."

That wouldn't work, because you'd be accessing a member of a unfinished object. That's dangerous in itself. It's like doing this:

1
2
3
class Object { int Member; };

Object NewObject.Member = 10; // Error. NewObject isn't yet fully constructed. 

Wazzak
Last edited on
@dadabe
Don't make assumptions before you know the facts.

Why? Ok the final destruction involves calling the destructor

What "final destruction"?

which only was performed, because the compiler developers didn't make the optimal implementation.

That's nonsense. The compiler does what the standard says. A nameless object is temporary, so the following statement create an Cat object and immediately destroys it:
CatClass("Frisky");


There shouldn't be much difference between:

1
2
3
4
5
6
int a = 5;

and 

int a;
a = 5;

There is a difference, the first initializes a to 5 (if a had a class type, that means calling a constructor), the second is an assignment (that means calling operator=).

And an assignment also is such a special case.

How do you even arrive at making such statement? No, it isn't.

But the compiler could do this.

No. If the constructor used in such an assignment and/or operator= have side effects, they must take place.
Aside from that, the compiler is free to perform whatever optimizations it wants to as long as it doesn't change the behavior of the program. However, that has nothing to do with the issues at hand.

Edit: this is the relevant part of the standard (12.8.32):
[...] - when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

A similar clause for operator= would not work, because at the time of the assignment the target is already constructed, so you cannot "construct the temporary object directly into the target".
Last edited on
closed account (4z0M4iN6)
@Athar

Maybe we first should argue more practical than technical? Because the discussion becomes a little bit too technically for beginners - oh not for me.

I think, there is some confusion about, what is an object and what is a container.

For example I have a horse. And this horse stays in a stable, which is just fitting for the horse. And at the door of the stable is a label with the name of the horse.

The question is now, what's the object? Is it the stable and the horse is it's content? Or is it the horse and the stable is it's container?

My opinion is, it's the horse.

If the stable is old, it could break down, so that it is destroyed. And if this happens, also the horse will be dead (also become destroyed). If I know this, I could move the horse to a new fine stable, before this happens. And when the old stable collapses, my horse will be well.

It seems to me, that some people think, because the stable has a label with the name of the horse at the door, the stable would be the horse, and when it collapses, the horse has to be destroyed.

Maybe you can understand, that I don't like such ideas about destroying my horse, when there is no such neccessity.

And maybe, we should imagine variables not as the objects, but the containers of objects. If we have a basket with the cat inside, so we also have the cat.

And the compiler should be a tool, what does, what we want.
Sometimes I want a new basket with a new cat. So I write:

CatClass NewBasket = CatClass("NewCat");

Maybe it's easy to bring me this. Only have to go to a cat shop, buy a new basket and a new cat, put the cat in the basket and bring it.

If I have already a basket, this job will become more difficult, for example:

CatClass MyBasket;
MyBasket = CatClass("New Cat");

My basket is at home. And you don't have it. How can you transport the cat? Oh that's your problem, not mine. I only want, that you bring the cat and put it in my basket.

And then you come and bring me a dead cat? And tell me is has to be so, and this would exactly be the correct way, because I already had a basket?

No I was wrong. You bring me a nice living cat. But you used another basket for the transport. And because the cat made this basket dirty, you throw it away and destroy it. And because you think - I don't reason why - the cat would have been still inside and also should be dead now, you come back and kill my cat.

This is really very difficult to understand for me. But I have some reason to think, that you are not quite right. But now I have to sleep.

Maybe tomorrow we know something more about this.

Oh I found an interesting web site:

http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/

Here the author wrote:

The purpose of the copy constructor and the assignment operator are almost equivalent — both copy one object to another. However, the assignment operator copies to existing objects, and the copy constructor copies to newly created objects.


And further he wrote:

If a new object has to be created before the copying can occur, the copy constructor is used.
...
There are three general cases where the copy constructor is called instead of the assignment operator:
...
2. When passing an object by value.
3. When an object is returned from a function by value.


This means, your assumptions, that it should be the operator= were not true.

Now we should find also something about the lifetime of an object.

My opinion is, the cat should not have been copied but moved. And on the stack is only the empty basket. And it still is alive and it's lifetime hasn't ended. Maybe we can find more about this somewhere.
Last edited on
Try to keep your posts short.

One thing you mentioned:
If I have already a basket, this job will become more difficult, for example:

CatClass MyBasket;
MyBasket = CatClass("New Cat");

This seems to be one of the things you misunderstand. An instance of a class Cat is not a container or "cat basket", it is a cat. It sounds like you are confusing the mechanics with Java or C#.

This means, your assumptions, that it should be the operator= were not true.

I wasn't making assumptions, I was stating facts. What is "it" and who should be what?
Last edited on
closed account (4z0M4iN6)
@Athar

I wasn't making assumptions, I was stating facts. What is "it" and who should be what?

Yes you are right about the facts of MS C++.

I extended my compiler test program and saw, the copy constructor isn't used in any case.

Cases 4, 5 and 7 use the assignment operator.
The other cases intiate the object directly in the right place.
And also case 6, which was a little bit astonishing:

CompilerTest Object6 = ReturnCompilerTest("UsedReturnObject1");

This is exactly the optimal implementation.

And my opinion is, this also would be the optimal place for case 5 and 7, because it's the fastest and shortest way and because we wouldn't get a bug, when we write:

ptrGlobalCat = this

at initialization time.

Yes I know, what you would tell me, I never should do this, because of the facts.

The question is only, are these the facts of C++ or the facts of MS C++?

Others write about C++, like the author of the mentioned web site and tell other facts. And people, who used other compilers, complain much, that the MS C++ compilers don't understand the basics of C++.

Maybe I have some time today and can install linux. It would be interesting to have a look, what the gcc compiler does.

This seems to be one of the things you misunderstand. An instance of a class Cat is not a container or "cat basket", it is a cat. It sounds like you are confusing the mechanics with Java or C#.

You think, I don't understand, what an object is? What do you think about a GUI object Cat?

You can handle it with variables, with pointers, you can throw it in the container Form1, where you can see it and throw all variables away. There is is list of the contents of the container Form1 und you can pick it up again. You can move it were you want, from window to panel, hide it in an array save it in a file. Copy the file on an USB stick, carry your cat with the USB stick everywhere you want.

This is, what I understand, what is an object. And a good compiler should allow me to do all with my cat, what I want.
Last edited on
C++ has a definition of what an object is. Please don't make up your own definition.
Last edited on
dude you might want to make sure you actually know what the heck your talking about before attempting to instruct others on what is the "proper" way to do something. I have no idea what language your coming from but its not C++.

this is just scary.
closed account (4z0M4iN6)
@Athar

Now I found, what I was looking for.

You were right about the assignment operator, but me too. I only was a little bit too far in the future.

You thought of an assignment copy operator.
And me thought of an assignment move operator.

The last don't exist for Visual Studio 2008.
And an automatically generation of the assignment move operator will not be implemented in VC11 due to time and source constraints, as you can read here:

http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx

But what I know now about my work around:

Calling CatFrisky.~CatClass() was syntactically quite correct. I red in ISO/IEC N3242:

Chapter 3.8: Object Lifetime, item 4:

For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released

And You are the expert for programming in MS C++ (not future versions).
And me is an expert in imagination, how the compiler would become a very good tool, without having to do such terrible work arounds.

Ok, it's no bugs it's only too early. Maybe in one, two or three years the new features will be available.
No, dadabe, you're wrong. Calling the destructor is never correct. Move vs Copy does not fix your issue.

To be honest, I think you've been licking too many spoons lately.
++i = i++ + ++i + i ++; is "syntactically correct". Just because something compiles doesn't mean it's a good idea.
closed account (zb0S216C)
Gaminic wrote:
"Calling the destructor is never correct."

With the exception of placement new.

Wazzak
Last edited on
closed account (4z0M4iN6)
Gaminic wrote:
Move vs Copy does not fix your issue.

It's exactly, what I need. The temporary object is moved to it's destination. At the stack or whereever is only left an empty storage (without the object) and for this storage no destructor will be called!!!
At the stack or whereever is only left an empty storage (without the object) and for this storage no destructor will be called!!!

Bullshit. The moved object is destroyed like any other.
Then again, whether you're spoonlicker or not, you seem to be a troll, so this discussion never had any point.
Last edited on
closed account (4z0M4iN6)
Bullshit. The moved object is destroyed like any other.

Yes and exactly this is the point where to hit the bull's eye. It's destroyed like any other block-scope variables:
The storage for these entities lasts until the block in which they are created exits. (ISO/IEC N3242=11-0012 chapter 3.7.3.1)

And not only like a temporary object:
Temporary objects are destroyed as the last step
in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

You can download this C++ bible at:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf





The only reason the move assignment operator is used without having to use std::move is because it is a temporary object.
Pages: 1234