Remix.run Logo
HarHarVeryFunny a day ago

No - you are confusing C and C++.

In C a structure passed by value will just be shallow-copied.

In C++ a structure/class passed by value will by copied using whatever copy constructor is defined by the structure type. If there is no explicitly defined copy constructor, then a default copy constructor will be used that does member-wise copy using the member's copy constructors.

So, unless you have chosen to shoot yourself in the foot by defining a class who's copy constructor doesn't do a deep copy, then C++ pass-by-value will indeed do a deep copy.

The case of a structure with a pointer member (e.g. maybe you defined your own string class) is certainly one where you would need to define an appropriate copy constructor, and not doing so would indeed be shooting yourself in the foot.

Maxatar a day ago | parent [-]

>So, unless you have chosen to shoot yourself in the foot by defining a class who's copy constructor doesn't do a deep copy, then C++ pass-by-value will indeed do a deep copy.

You either are misspeaking, deeply confused, or quite possibly both.

HarHarVeryFunny a day ago | parent [-]

Do you agree that C++ pass-by-value is using copy constructors?

Do you agree that the copy constrictors of the C++ standard library (STL) all do deep copy?

Do you agree that if you write your own class with a raw pointer member, you would need to write a copy constructor?

So, what exactly are you disagreeing about ?!

You seem to be saying that if you wrote a C-style structure (no constructors) with a pointer member, then C++ would behave like C, which is true, but irrelevant. We're talking about C++ vs C, but since C++ is a superset of C, then yes you can still screw yourself C-style if you choose to.

Maxatar a day ago | parent [-]

>Do you agree that C++ pass-by-value is using copy constructors?

C++ is an incredibly complex language that it's almost never the case that you can make a categorical statement this simple and have it be true or false.

In C++, pass by value may or may not make use of a copy constructor depending on a set of very complex rules. For example passing an rvalue by value for a class type which defines a move constructor may use the move constructor rather than the copy constructor (emphasis on may because even that isn't guaranteed). Passing an lvalue for a class type may or may not invoke the copy constructor depending on specific language rules regarding copy elision. For fundamental types, there is no copy constructor whatsoever.

>Do you agree that the copy constrictors of the C++ standard library (STL) all do deep copy?

I absolutely do not agree with this, in fact believing so is absurd and I can't possibly fathom what would lead you to believe this. The principle the C++ standard uses for copying objects is based on Alexander Stepanov's "Elements of Programming" where he defines the concept of a regular type. A regular type does not require making a deep or a shallow copy, what it requires is that copies satisfy the following:

The copy must preserve equivalence (if a == b, then copy(a) == copy(b)).

The copy must be idempotent in meaning.

Copying must not have side effects on the source.

So as an example a std::string_view can be copied, but making a copy of it is constant O(1) in both time and space. What is required is that after performing a copy, the original source remains unchanged, operator == returns true between the source and the copy, and that making a copy is an idempotent operation.

You can extend this further for other collections as well, a std::vector<Foo*> does not end up making deep copies of the pointers being contained, what it does do is satisfy the conditions for being a regular type.

>Do you agree that if you write your own class with a raw pointer member, you would need to write a copy constructor?

Absolutely not. Just sticking to the existing standard library types you have things like std::span, all of the iterator types which use pointers under the hood, std::initializer_list, std::string_view was already covered.

To be blunt, you're expressing a very superficial understanding of a very complex topic that's part of an even more complex language.

In general my advice is... never assume that things in C++ are as simple and straight forward as they appear. If you're using a subset of the language that works for you, great, like really good job and continue doing so and I absolutely don't want to discourage you from using the subet of C++ that works for your use case... but don't then confuse this subset for being representative of either the language as a whole or representative of the vast use cases that C++ belongs to and recognize that the advice you give which works so well for you may actually be really bad advice for someone else working within a different subset of the language.

HarHarVeryFunny 12 hours ago | parent [-]

> I absolutely do not agree with this, in fact believing so is absurd and I can't possibly fathom what would lead you to believe this.

Its not clear if you have any experience with C++ or you are just trolling.

Try using STL containers like std::list, vector, map, set and see how they behave. Or just read the documentation.

You bring up move vs copy constructors... which is irrelevant since a properly implemented move should give the same result as a copy other than the side effect of invalidating the source.

You bother to point out that fundamental types have no constructor. Thank you einstein.

> In general my advice is...

Worthless.

I was programming in C++ for over a quarter of a century, up to and including C++17, before I stopping a year ago.

I've written massive libraries and frameworks in C++ consisting of 10's of thousands of lines of code, and eagerly using all the latest language features as soon as a better way of doing things was supported.

You are just an ignorant twat.