News for hackers. Stuff that matters.
Re:Writing Good C++14 by Default [pdf] by Gankro on Wednesday September 23, 2015 @10:31AM (#10265176)
My answer to that is "you shouldn't want to deep copy on assignment". It's a performance trap and makes the code harder to understand. Without pervasive copy/assignment/move ctors you would be surprised to see how little you actually want to explicitly invoke them (usecases may vary, of course).

Sadly this is the path that C++ has taken.

Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @12:04PM (#10265864)
Shallow copy on assignment is dangerous because it leads toward double frees and therefore chaos in your heap.

Ironically, the original topic (upthread quite a ways) was pointer safety...

Re:Writing Good C++14 by Default [pdf] by Gankro on Wednesday September 23, 2015 @12:25PM (#10266007)
Yes, backwards compatability with C makes this a hard problem, but this is exactly what affine typing fixes: assignment is a shallow copy, but the old copy becomes inaccessible.
Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @12:56PM (#10266224)
I don't think it's "backward compatibility with C". It's that C++ deliberately lets you go down to raw pointers. This lets you write things like memory allocators in C++. Yes, that makes it a hard problem to do only shallow copy, which gets us back to overloading assignment operators.

It sounds like you want C++ to be something other than it is. That's fine, for you. Use something else. But C++ is the way it is for a reason. A lot of people find those parts that you don't like to make it a more useful tool for things that we actually do.

Re:Writing Good C++14 by Default [pdf] by pjmlp on Wednesday September 23, 2015 @04:43PM (#10268034)
> I don't think it's "backward compatibility with C". It's that C++ deliberately lets you go down to raw pointers.

Being able to be copy-paste compatible with C is "backward compatibility with C".

Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @05:27PM (#10268360)
Yes, C++ is that (almost). But that attribute of C++ is not the source of the problems that we're talking about here.

I mean, yes, in a sense it is, in that C had shallow copy of structs (IIRC), but... let's review, shall we?

pjmlp whined about operator overloading, about how it made code difficult to understand. Gankro specifically singled out copy and assignment overloading as being unnecessary and confusing. jawilson2 raised the question of deep vs. shallow copying (implying that you need to overload copy and assignment in order to easily do deep copy). Gankro replied that you shouldn't want to do deep copy on assignment. I pointed out the problem with his/her view, namely, possible memory corruption. Gankro relied, blaming this on backward compatibility with C. I explained that it's not backward compatibility per se that creates the problem, it's the ability to have pointers. My point was that C++ was deliberately going to have pointers - it wasn't just because of backward compatibility. You argue that C++ is in fact backward compatible. In the context of the conversation, so what? We're not questioning whether C++ is C-compatible. It is, but that's not the point.

The point is, even if C++ were deliberately not C-compatible, if it let you play with pointers (and given the intent of C++, it would) it would still have the issue of shallow vs. deep copy, and overloading assignment and copy would still be the solution.

Re:Writing Good C++14 by Default [pdf] by Gankro on Wednesday September 23, 2015 @11:02PM (#10269586)
You have completely ignored the actually interesting point of my argument, and focused on pointless details. In particular, my statement on affine types. Or, in C++ terms, move semantics by default, instead of copy semantics by default.

Raw pointers don't deep copy (what would that even mean?) so clearly you're only talking about structs that impose special semantics on raw pointers. If those structs were affine (assignment was a move which marked the old copy as unusable), then there would be no need to overload assignment for that facet of safety. They would just be in a different place, which would be fine.

The only really special case is having a pointer into yourself (really into yourself, not just into some fixed heap location you own -- basically, caring about your own location in memory). This is the only thing, as far as I can tell, that C++'s approach gains over affinity. Personally I consider it a bit of a nightmarish thing to do without GC (it's a bit nasty even with it TBH), but I know all too well that people will demand anything and everything; especially once they're used to it. Although this wouldn't completely preclude this pattern, it just means you can't wrap it up in a pseudo-safe way -- particularly if you want to pass it to arbitrary client code.

However this would be a massive break from C, which is copy semantics all the way down. I suppose C++ could have further given the `class` keyword meaning by making all classes affine. I dunno if people would have tolerated that kind of difference at the time. Sort of a soft breaking change, yaknow? Then again, maybe overloading `=` is already a breaking change in that regard.

shrug

language design is hard

Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Thursday September 24, 2015 @12:22PM (#10272509)
True, I was not addressing the main point of what you said, and quibbling about your wording on a side point.

So before C++ assignment and copy operator overloading, you'd have a C struct, and assignment was a bitwise copy. If the original is destroyed after that, you're safe. If it's not, and the struct contains a pointer to allocated memory, you're going to have trouble unless you're very careful about who owns the memory.

But even then, you had situations where you wanted to truly make a (deep) copy. That took a call to a function that knew the structure, and which parts to deep copy. So the need to do that was still there.

So if we move to affine types or move semantics or whatever, the need for deep copy doesn't go away. If you don't have an overloaded assignment operator or copy operator, you're going to have a function of a different name that does the exact same operations. So the need for both operations doesn't go away. But the move/affine approach does make the double-free problem go away (as does the current C++ overloaded copy approach).

> language design is hard

Yeah. Somebody wants every possible action to be doable, and different people want different actions to be easy or the default. Nobody's going to be completely happy.

Re:Writing Good C++14 by Default [pdf] by Gankro on Thursday September 24, 2015 @03:16PM (#10273930)
I would personally arguing that a deep copy necessitating an explicit function call is a good thing, though. It makes potentially expensive operations obvious, and improves your ability to reason about program behaviour.
Re:Writing Good C++14 by Default [pdf] by pjmlp on Wednesday September 23, 2015 @06:14PM (#10268626)
> pjmlp whined about operator overloading, about how it made code difficult to understand

Learn to read, shall you?

I am 100% in favour of operator overloading.

Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @06:41PM (#10268744)
I never said you weren't. I said that your statement about backward compatibility, while true, was completely irrelevant to the conversation.

[Edit: I take it back. I did say you whined about operator overloading, when in fact you were quoting arcticbull.]

Re:Writing Good C++14 by Default [pdf] by pjmlp on Thursday September 24, 2015 @03:09AM (#10270290)
Ok
Re:Writing Good C++14 by Default [pdf] by steveklabnik on Wednesday September 23, 2015 @12:11PM (#10265908)
... however, Rust's semantics specifically prevent this double free.
Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @12:50PM (#10266189)
Which, if we were talking about Rust here, might be relevant. But in this thread of the conversation, we're talking about C++ operator overloading and why you need it for deep copying on assignment. In the immediate context, how Rust does it is not relevant.
Re:Writing Good C++14 by Default [pdf] by dbaupp on Wednesday September 23, 2015 @07:00PM (#10268842)
The discussio is about strategies to avoid the double-frees problem in a hypothetical "C++ with changes", and Rust's is one example. Seems fine and useful to give examples. (That's what Gankro's comment is too: Rust's strategy is affine types.)
Re:Writing Good C++14 by Default [pdf] by AnimalMuppet on Wednesday September 23, 2015 @07:18PM (#10268913)
Could be I missed something, but I looked all the way back to the root of this thread, and I didn't see (in any of the direct ancestors) anywhere where the topic was a hypothetical "C++ with changes".