2

Is is possible for rust to have shallow copies, because it would appear that a move replaces a shallow copy?

roberthayek
  • 167
  • 2
  • 10
  • 6
    Trying to define a general concept of "shallow" and "deep" copy and then expecting a language to "support" this is a mistake in the first place. – Sebastian Redl Nov 12 '18 at 07:32

1 Answers1

2

You have to differentiate based on the underlying type.

You can't do a shallow copy of struct Foo(String); because two instances of Foo would point at the very same String, which would violate the strict aliasing rule .

However, if you are having a reference counter, e.g. struct Foo(Rc<String>); it is possible, because Rc will prevent you from doing unsafe things, e.g. having a mutable reference, when there are others references on the String.

It is also possible for types that implement [Clone] to make a "shallow" copy, because Copy implies, that the type can be copied by using memcpy (e.g. a u32 or a &T).

What is the difference between Copy and Clone? is also very worth reading.


So, in general no: Exceptions are reference counted structs (Rc or Arc) , Cloneables, or references (&T), because they don't violate the strict aliasing rule.

hellow
  • 12,430
  • 7
  • 56
  • 79
  • 2
    strict aliasing is not only about two pointer or reference to the same data, there also need to have the same type (expections types in C are character type). Put it simply you can't have a u32 * and a u16 * that refer to the same memory because the compiler assume it's not possible. Strict mean you can only have u32 * that refer the this memory (or char * in C), Strict != No aliasing. I don't know if it's true in Rust, but I will not take the risk, this kind of bug is hard to find. – Stargateur Nov 12 '18 at 09:43
  • Thanks for that. I would like to add, that safe rust won't let you do that, so there is no worry about that. – hellow Nov 12 '18 at 09:50
  • 1
    Rust does not have a strict aliasing rule for pointers. Even pointers of different types are allowed to refer to the same memory. Of course you need unsafe code to dereference them. – Sven Marnach Nov 12 '18 at 09:56
  • This is an old comment, I assume things have changed in the language from then. I think it is UB to cast across types. The memory model is still not settled but every approach I have seen with stack of borrows and strict provenance are way more strict. Casting from pointers to integers and back is UB, unions are only allowed for types without Drop, and transmute only allows usage for types with exact same layout, so basically only repr(c) – Augusto Hack Nov 15 '22 at 17:57
  • Can you tell me what you are refering to? I don't talk about casting or transmuting at all?Not sure what you mean here. – hellow Nov 15 '22 at 18:08