Copy-in, Copy-out and reference semantics
I see this question pop-up every now and then on various forums and generally within conversations.
By default in languages like C# and C++ (and tonnes of others) copy-in semantics are used when dealing with the objects of formal method parameters.
Each can be viewed as read (copy-in), write (copy-out) and read-write (reference).
Although I have not checked my assumption is that modern, sophisticated compilers will in fact embrace the most efficient semantics in any particular scenario, e.g. say I have a method that takes a single argument by default I am using copy-in semantics and in the method I am not writing to that parameter only reading thus the compiler under the hood could just pass by reference which is more optimal.
Copy-in can be expensive if the formal parameter's are large in nature, e.g. large data structures etc, copy-out semantics are also expensive as they copy-in and then "push" the data back out again writing, references do neither but are more error prone.
using System;
namespace CopySemantics
{
class Program
{
static void Main()
{
Person p = new Person("Granville", "Barnett");
CopyIn(p);
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
CopyOut(out p);
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
Reference(ref p);
Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
}
public static void CopyIn(Person person)
{
/* copy-in semantics, this method uses a local copy of
* the formal parameter if value type otherwise person
* pointer value */
person.FirstName = "Alan";
person.LastName = "Shearer";
}
public static void CopyOut(out Person person)
{
/* Same as copy-in semantics but value is written to
* formal parameter object/value type. */
person = new Person("John", "Edwards");
}
public static void Reference(ref Person person)
{
/* no copy-in or copy-out semantics used here, we are
* always dealing with the object passed in the formal
* parameter */
person.FirstName = "Bill";
person.LastName = "Gates";
}
}
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
}
Hopefully that clears some stuff up - but I would expect the C# or C++ compiler being used to go ahead and do some checks and then use the most efficient semantics anyway.
Apologies if the example is poor, I just did this off the top of my head this minute :-(
Note: copy out semantics are not in C++, you must use reference (read-write) semantics (&).
Note: these semantics don't just apply to modern C++ compilers or the C# compiler, rather this is what most commercial grade compilers will do in some optimisation phase.