diff --git a/arbor/memory/device_coordinator.hpp b/arbor/memory/device_coordinator.hpp
index f9b3c864d828a68d68ea79b63da2937a13283fac..ab8733d732add5ad212f72890fcd717405c05168 100644
--- a/arbor/memory/device_coordinator.hpp
+++ b/arbor/memory/device_coordinator.hpp
@@ -80,10 +80,19 @@ public:
         return *this;
     }
 
+    // Assigning to a reference will copy the referenced memory
     device_reference& operator=(const device_reference& ref) {
-        gpu_memcpy_d2d(pointer_, ref.pointer_, sizeof(T));
+        if (this != &ref) {
+            gpu_memcpy_d2d(pointer_, ref.pointer_, sizeof(T));
+        }
+        return *this;
     }
 
+    // No empty references
+    device_reference() = delete;
+    // Copying a reference is a shallow copy
+    device_reference(const device_reference& ref) = default;
+
     operator T() const {
         T tmp;
         gpu_memcpy_d2h(&tmp, pointer_, sizeof(T));