Granville Barnett

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.

Posted: Nov 14 2007, 12:21 PM by gbarnett | with 2 comment(s)
Filed under: , , ,

Comments

No Comments