A Deep Dive Into 'Pass By Value' and 'Pass By Reference' With C# Examples

Updated on February 6, 2019
sirama profile image

I am a software engineer. I have been working with C++, MFC, and .net technologies for 15 years. I like playing video games & reading books.

1. Introduction

In CSharp there are two major groups of Types. One is Predefined Primitive Data Types and other one is Class Types. We often hear that the former is Value Type and the later one is Reference Type. In this Article, we will explore how these Types behave when they are passed to a function as Value and as Reference.

2. The Point2D Class

This class contains two member variables (x, y). These members represent the co-ordinate of a point. A constructor which takes two parameters from the caller initializes these two members. We use SetXY function to make a modification to the members. The print function writes current co-ordinate to the Console Output window.

We will create instances of these class to explore various parameter passing techniques. Code for this class is shown below:

//Sample 01: A Simple Point Class
public class Point2D
{
    private int x;
    private int y;

    public Point2D(int X, int Y)
    {
        x = X;
        y = Y;
    }

    public void Setxy(int Valx, int Valy)
    {
        x = Valx; 
        y = Valy;
    }

    public void Print()
    {
        Console.WriteLine("Content of Point2D :" 
            + x + "," + y);
    }
}

We will introduce one more class called TestFunc. This is a static class and will have all our Test Function for exploring various parameter passing methods. The skeleton of the class is below:

static class TestFunc
{

}

3. Primitive Types

A Primitive Type is a pre-defined data type that comes with the language and it directly represents a basic data like an integer or a character. Take a look at the below piece of code:

void AFunctionX()
{
    int p = 20;
}

In the above function, we have only one variable called F. The local stack frame of the function AFunctionX allocates space for the variable F to store the value of 15. Look at the below depiction

Primitive Data Type Allocated on Stack
Primitive Data Type Allocated on Stack | Source

In the above picture, we can see that the stack frame knows existence of a variable, p by its base address (For example, 0x79BC) on the stack frame and maps that to the actual address location 0x3830 on the same stack frame at a certain offset. The value 20 assigned in the function is stored at Stack Memory Location, 0x3830. We call this as a Variable Name Binding or simply "Name Binding". Here the name p is bound to the address 0x3830. Any read or write request on p takes place on the memory location 0x3830.

Now let us explore various ways of passing primitive data types to a function and its behavior.

3.1 Primitive Types - Pass by Value

We define the below function in the TestFunc static class. This function takes an integer as an argument. Inside the function we change the value of the argument to 15.

//Sample 02: Function Taking Arguments 
//           Pass By Value
public static void PassByValFunc(int x)
{
    //Print Value Received
    Console.WriteLine("PassByValFunc: Receiving x " +
        "by Value. The Value is:{0}", x);

    //Change value of x and Print
    x = 15;
    //Print Value Received
    Console.WriteLine("PassByValFunc: After Changing " +
    "Value, x=" + x);
}

We call above defined function from our main program. First, we declare and initialize an integer variable. Before making a call to the function, the value of the integer is 20 and we know that the function changes this value to 15 inside its body.

//Sample 03: Test Pass by Value
//Standard variables
int p = 20;
Console.WriteLine("Main: Before sending p " +
    "by Value. The Value in p is:{0}", p);
TestFunc.PassByValFunc(p);
Console.WriteLine("Main: After calling " +
    "PassByValFunc by Value. The Value in " +
    "p is:{0}", p);
Console.WriteLine();

The output of this simple code is given below:

Standard Types - Pass By Value Output
Standard Types - Pass By Value Output | Source

Here, the function PassByValFunc changes the passed in parameter value from 20 to 15. Once, function returns, the main still preserves the value 20. Now, look at the below depiction.

Primitive Type Pass By Value - Explained
Primitive Type Pass By Value - Explained | Source

First, we will look at the top portion of the picture. The picture shows that our execution stays at first statement which highlighted in yellow. At this stage, the call stack main has a name p defined at 79BC which binds to location 3830. Before calling this function, main program used the name p to assign a value of 20 in the memory location 3830 which stack frame. The called function defines name x inside its own stack frame at location 9796 and that bind to the memory location 773E. Since the parameter is passed by value, a copy occurs between p to x. In other words, the content of location 3830 is copied to the location 773E.

Now, we will explore the bottom portion of picture. The execution moves to the last statement. By this time, we already executed the assignment (x=15) and hence the content of 773E is changed to 15. But, the Stack Frame location 3830 of main is not modified. This is why we see main printing p as 20 after the function call.

3.2 Primitive Types - Pass by Reference with Ref Keyword

In the previous section, we saw passing an argument by value and we actually passed a primitive type as a parameter. Now, we will examine the behavior by sending the same primitive data type as a reference. We wrote a function in our static class to receive the argument By Reference. The code is below:

//Sample 04: Function Taking Arguments
//          Pass By Reference (Ref)
public static void PassByRefFunc(ref int x)
{
    //Print Value Received
    Console.WriteLine("PassByRefFunc: Receiving x " +
        "by Value. The Value is:{0}", x);

    //Change value of x and Print
    x = 45;

    //Print the changed value
    Console.WriteLine("PassByRefFunc: After Changing " +
    "Value, x=" + x);
}

We should note the usage of the "ref " keyword in the function Argument List. In this function, we are changing the passed in value to 45 and printing the content of the name x before and after modifying it. Now, we write a calling code in the main program which is shown below:

//Sample 05: Test Pass by Reference
//Standard variables (ref)
int r = 15;
Console.WriteLine("Main: Before sending r " +
    "by Reference. The Value in r is:{0}", r);
TestFunc.PassByRefFunc(ref r);
Console.WriteLine("Main: After calling " +
    "PassByValFunc by Value. The Value in " +
    "r is:{0}", r);
Console.WriteLine();

Here, we are first assign an integer variable with a value of 15. After this, we call the function and pass the variable by reference. We should note the usage of the keyword ref here. We need to specify the ref keyword both in the Called Function's Argument List as well as Parameter List of calling code. The below screenshot shows the output of this piece of code:

Standard Types - Pass By Ref Output
Standard Types - Pass By Ref Output | Source

By looking at the output, we may wonder why Main function is printing value of r is 45 which was changed in the called function, not in the Main function. Now, we will explore it. Remember, we passed the parameter by reference and have a look at below depiction:

Primitive Type Pass By Reference - Explained
Primitive Type Pass By Reference - Explained | Source

The top portion of the picture shows that execution stays at the top of the function before changing the value of x. At this stage, Main stack frame address 3830 is associated to name r and holds a value 15. There is no difference here when we pass the parameter By Value or By Reference. But, in the called function Stack Frame, no memory is reserved for x. Here, x also binds to the calling stack location 3830 because of the mention of the ref keyword. Now memory location of Main function stack frame 3830 is bound by two names r and x.

Now, we will explore the bottom portion of the depiction. Execution stays at the end of the function and it changed stack frame location to 45 through the name x. Since x and r both binds to memory location 3839, we see main function printing 45 in the output result. So, when we pass a primitive type variable as a reference, the content changed in the called function gets reflected in the main function. Note, the binding (x binding to location 3830) will get scraped after the function returns.

3.3 Primitive Types - Pass by Reference with Out Keyword

When we pass a parameter By Reference with mention of “ref” keyword, the compiler expects that the parameter was already initialized. But, in some situation, the calling function just declares a primitive type and it will get assigned first in the called function. To handle this situation, c-sharp introduced the “out” keyword which be specified in the function signature and while calling that function.

Now, we can write below given code in our static class:

//Sample 06: Function Taking Arguments
//          Pass By Reference (out)
public static void PassByrefOut(out int x)
{
    //Assign value inside the function
    x = 10;

    //Print the changed value
    Console.WriteLine("PassByRefFunc: After Changing " +
    "Value, x=" + x);
}

Here, in the code we assign a value 10 to the local variable x and then printing the value. This works same like the pass by reference. To pass a variable without initializing, we marked the parameter x with the “out” keyword. The out keyword expects that function must assign a value to x before it returns. Now, let we write the calling code as shown below:

//Sample 07: Test Pass by Reference
//Standard variables (out)
int t;
TestFunc.PassByrefOut(out t);

Console.WriteLine("Main: After calling " +
    "PassByrefOut by Value. The Value in " +
    "t is:{0}", t);
Console.WriteLine();

The variable t is declared here and then we call the function. We pass the parameter t with the keyword out. This tells the compiler that the variable may not be initialized here and the function will assign a valid value to it. Since, “out” acts as pass by reference, the assigned value in the called function can be seen here. The output of the code is below:

Standard Types-Pass By Ref with "out" Output
Standard Types-Pass By Ref with "out" Output | Source

4. Reference Types

When we say Reference Type, we mean that the memory location of data is stored by the type. All class instance that we create in C-sharp is reference type. For better understanding, we will look at the code given below

void AFunctionX()
{
    MyClass obj = new MyClass();
}

In the code, we are creating an instance of class MyClass and stored its reference in obj. Using this variable obj, we can access the members of the class. Now, we will look at the depiction below:

Reference Type Heap Allocation, Address in stack
Reference Type Heap Allocation, Address in stack | Source

The name obj maintained by the Stack Frame of function (AFunctionX), binds that to the location 3830. Unlike primitive data type, the memory location holds address of some other memory location. Hence, we call obj as Reference Type. Note that in Value Type, the location should have been assigned with a direct value (Ex: int x=15).

When we create “Class Objects” using the keyword new or any other types with new, the memory will be claimed at the heap location. In our example, memory required for the object of type MyClass is allocated in the heap at location 5719. The variable obj holds the memory location of that heap and memory required to hold that address is given in the stack (3830). Since the name obj holds or refers address of the heap location, we call it as Reference Type.

4.1 Reference Type - Pass by Value

Now, we will explore Pass By Value for a Reference Type. We will write a function in our static class for that. The function is given below:

//Sample 08: Pass by Value (Object)
public static void PassByValFunc(Point2D theObj, int Mode)
{
    if (Mode == 0)
    {
        theObj.Setxy(7, 8);
        Console.WriteLine("New Value Assigned inside " +
            "PassByValFunc");
        theObj.Print();
    }
    else if(Mode == 1)
    {
        theObj = new Point2D(100, 75);
        Console.WriteLine("Parameter theObj points " +
            "to New object inside PassByValFunc");
        theObj.Print();
    }
}

This function receives two arguments. By this time, we can answer that first parameter is a Reference Type and the second one is Value Type. When mode is zero, we try to change data members of the Point2D instance. This means, we are changing the heap memory content. When mode is one, we try to allocate new Point2D object and hold that in the variable called theobj. This means, we try to change the stack location to hold the new address. Alright! Now, we will look at the calling code:

//Sample 09: Passing Objects by Value
//9.1 Create new 2dPoint
Point2D One = new Point2D(5, 10);
Console.WriteLine("Main: Point2d Object One created");
Console.WriteLine("Its content are:");
One.Print();

//9.2 Pass by Value
//9.2.1 Change only contained values
Console.WriteLine("Calling PassByValFunc(One, 0)");
TestFunc.PassByValFunc(One, 0);
Console.WriteLine("After Calling PassByValFunc(One, 0)");
One.Print();

In the calling code, first we allocate the Point2D object on the heap and initializing the point co-ordinates to 5 and 10. Then, we are passing the reference to this object (One) by value to the function PassByValFunc.

4.1.1 Changing the Content

The second argument passed to the function is zero. The function sees, mode as zero and changes the co-ordinate values to 7 and 8. Have a look at the below depiction:


Reference Type - Pass by Value - Change heap content
Reference Type - Pass by Value - Change heap content | Source

We will look at the top half of the picture. Since we pass the reference (One) by value, the function allocates new location in the stack at 0x773E and stores the address of the heap location 0x3136. At this stage (When execution is at the if conditional statement which is highlighted above), there are two reference pointing to the same location 0x3136. In modern programming language like C-Sharp and Java, we say Reference-Counting for the heap location is two. One is from the Calling function through reference One and other one is from the called function through reference theObj.

The bottom portion of the picture shows that the content of the heap is changed through the reference theObj. The call we made to the function Setxy changed the content of the Heap location which is pointed by two reference objects. When the function returns, in the calling function we refer this changed heap memory location through Name “One” which bound to 0x3830. This is how the calling function prints 7 and 8 as co-ordinate values.

The output of the above shown code is below:


Reference Types Pass-By-Value Output 1
Reference Types Pass-By-Value Output 1 | Source

4.1.2 Changing the Reference

In the previous section, we asked the function to change the Value of the heap by passing zero as a value for the Mode argument. Now, we request the function to change the reference itself. Have a look at the calling code below:

//9.2.2 Change the Reference itself.
Console.WriteLine("Calling PassByValFunc(One, 1)");
TestFunc.PassByValFunc(One, 1);
Console.WriteLine("After Calling PassByValFunc(One, 1)");
One.Print();
Console.WriteLine();

To explain what is happening inside the function, we need to look at the depiction below:

Reference Types- Pass-By-Value - Changing heap location
Reference Types- Pass-By-Value - Changing heap location | Source

When mode is 1, we allocate new heap and assign that to the local name, “theObj”. Now, we will look at the top portion of the picture. Everything is same as in the previous section as we do not touch the reference, “theObj”.

Now, look at the bottom portion of the picture. Here, we allocate the new heap at location 0x7717 and initialize the heap with co-ordinate values 100, 75. At this stage, we have two name bindings called “One” and “theObj”. The name “One” belongs to calling stack binding to the location 0x3830, which points to old heap location 0x3136. Name “theObj” belongs to called Stack Frame binding to the location stack location 0x773E which points to heap location 0x7717. The code output shows 100,75 inside the function and 5,10 after we return from it. This because we read location 0x7717 inside the function and after we return we read the location 0x3136.

Note, once we return from the function, the stack frame for the function is cleared and there by the stack location 0x773E and the address 0x7717 stored in it. This reduces the Reference Count for the location 0x7717 from 1 to zero signaling the Garbage Collector that the heap location is 0x7717 is not in use.

The output of executing the code is given in the below screenshot:

Reference Types Pass-By-Value Output 2
Reference Types Pass-By-Value Output 2 | Source

4.2 Reference Type - Pass by Reference

In the previous section we examined passing an Object Reference “By Value” to a function. We will explore passing the Object Reference “By Reference”. First, we will write a function in our static class and the code for it given below:

//Sample 10: Pass by Reference with ref
public static void PassByRefFunc(ref Point2D theObj, 
int Mode)
{
    if (Mode == 0)
    {
        theObj.Setxy(7, 8);
        Console.WriteLine("New Value Assigned inside " +
            "PassByValFunc");
        theObj.Print();
    }
    else if (Mode == 1)
    {
        theObj = new Point2D(100, 75);
        Console.WriteLine("Parameter theObj points " +
            "to New object inside PassByValFunc");
        theObj.Print();
    }
}

Note, we specified ref keyword in the as part of the first parameter. It tells the compiler that the Objects reference is passed “By Reference”. We know what happens when we pass a Value-Type (Primitive Types) By Reference. In this section, we examine the same for Reference Types using our Point2D object references. The calling code of this function is given below:

//Sample 11: Passing Objects by Reference
//11.1 Create new 2dPoint
Point2D Two = new Point2D(5, 10);
Console.WriteLine("Main: Point2d Object Two created");
Console.WriteLine("Its content are:");
Two.Print();

//11.2 Pass by Ref
//11.2.1 Change only contained values
Console.WriteLine("Calling PassByRefFunc(Two, 0)");
TestFunc.PassByRefFunc(ref Two, 0);
Console.WriteLine("After Calling PassByRefFunc(Two, 0)");
Two.Print();

4.2.1 Changing the Content

Here, we do the same. But, at line 11, we pass the object reference “Two” with “ref” keyword. Also, we set the mode as 0 to examine the behavior of the changes in the heap content. Now, look at the below depiction:

Reference Type - Pass by Reference - Change heap content
Reference Type - Pass by Reference - Change heap content | Source

Top portion of the picture shows there are two Name Bindings to the Calling Stack location 0x3830. The name “Two” binds to its own Call Stack location 0x3830 and the name “theObj” from the called function also binds to this same location. The stack location 0x3830 contains address of the heap location 0x3136.

Now, we will look at the bottom portion. We called the SetXY function with new co-ordinate values 7,8. We use the name “theObj” to write into the Heap Location 0x3136. When the function returns, we read the same heap content using the name “Two”. Now, we are clear why we get 7,8 as co-ordinate values from the calling code after the function returns. The code output is below:

Reference Types Pass-By-Reference Output 1
Reference Types Pass-By-Reference Output 1 | Source

4.2.2 Changing the Reference

In the previous section, we changed the Heap Content and examined the behavior. Now, we will change the Stack Content (i.e.) we allocate a new heap and store the address in the Same Stack location. In the calling code we are setting the mode as 1 as shown below:

//11.2.2 Change the Reference itself.
Console.WriteLine("Calling PassByRefFunc(Two, 1)");
TestFunc.PassByRefFunc(ref Two, 1);
Console.WriteLine("After Calling PassByRefFunc(Two, 1)");
Two.Print();
Console.WriteLine();

Now, look at the below illustration:

Reference Types- Pass-By-Reference - Changing heap location
Reference Types- Pass-By-Reference - Changing heap location | Source

Now, look at the top portion of the picture. Once we enter the function, the heap location has two reference count Two, theObj. The bottom portion shows the snapshot of memory when execution stays at print function. At this stage, we allocated a new object in the Heap at location 0x7717. Then, stored this heap address through “theObj” name binding. The calling stack location 0x3830 (Remember it has two Name-Bindings Two, theObj) now stores new heap location 0x7717.

Since, the old heap location is overwritten by the new address 0x7717 and nobody points to it, this old heap location will be garbage collected. The code output is shown below:

Reference Types Pass-By-Reference Output 2
Reference Types Pass-By-Reference Output 2 | Source

4.3 Reference Type - Pass by Reference with Out Keyword

The behavior is same like previous section. Since, we specify "out" we can pass the reference without initializing it. The object will be allocated in the called function and given to the caller. Read the out behavior from the Primitive Types sections. The complete code example is given below.

Program.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace PassByRef
{
    class Program
    {
        static void Main(string[] args)
        {
            //Sample 03: Test Pass by Value
            //Standard variables
            int p = 20;
            Console.WriteLine("Main: Before sending p " +
                "by Value. The Value in p is:{0}", p);
            TestFunc.PassByValFunc(p);
            Console.WriteLine("Main: After calling " +
                "PassByValFunc by Value. The Value in " +
                "p is:{0}", p);
            Console.WriteLine();

            //Sample 05: Test Pass by Reference
            //Standard variables (ref)
            int r = 15;
            Console.WriteLine("Main: Before sending r " +
                "by Reference. The Value in r is:{0}", r);
            TestFunc.PassByRefFunc(ref r);
            Console.WriteLine("Main: After calling " +
                "PassByValFunc by Value. The Value in " +
                "r is:{0}", r);
            Console.WriteLine();

            //Sample 07: Test Pass by Reference
            //Standard variables (out)
            int t;
            TestFunc.PassByrefOut(out t);

            Console.WriteLine("Main: After calling " +
                "PassByrefOut by Value. The Value in " +
                "t is:{0}", t);
            Console.WriteLine();

            //Sample 09: Passing Objects by Value
            //9.1 Create new 2dPoint
            Point2D One = new Point2D(5, 10);
            Console.WriteLine("Main: Point2d Object One created");
            Console.WriteLine("Its content are:");
            One.Print();

            //9.2 Pass by Value
            //9.2.1 Change only contained values
            Console.WriteLine("Calling PassByValFunc(One, 0)");
            TestFunc.PassByValFunc(One, 0);
            Console.WriteLine("After Calling PassByValFunc(One, 0)");
            One.Print();

            //9.2.2 Change the Reference itself.
            Console.WriteLine("Calling PassByValFunc(One, 1)");
            TestFunc.PassByValFunc(One, 1);
            Console.WriteLine("After Calling PassByValFunc(One, 1)");
            One.Print();
            Console.WriteLine();

            //Sample 11: Passing Objects by Reference
            //11.1 Create new 2dPoint
            Point2D Two = new Point2D(5, 10);
            Console.WriteLine("Main: Point2d Object Two created");
            Console.WriteLine("Its content are:");
            Two.Print();

            //11.2 Pass by Ref
            //11.2.1 Change only contained values
            Console.WriteLine("Calling PassByRefFunc(Two, 0)");
            TestFunc.PassByRefFunc(ref Two, 0);
            Console.WriteLine("After Calling PassByRefFunc(Two, 0)");
            Two.Print();

            //11.2.2 Change the Reference itself.
            Console.WriteLine("Calling PassByRefFunc(Two, 1)");
            TestFunc.PassByRefFunc(ref Two, 1);
            Console.WriteLine("After Calling PassByRefFunc(Two, 1)");
            Two.Print();
            Console.WriteLine();

            //Sample 13: Passing Objects by Rerence with Out Keyword
            //13.1 Create new 2dPoint
            Point2D Three;
            Console.WriteLine("Main: Point2d Object Three Declared");
            Console.WriteLine("Its content are: Un-Initialized");

            //13.2 Change the Reference itself.
            Console.WriteLine("Calling PassByrefOut(Three)");
            TestFunc.PassByrefOut(out Three);
            Console.WriteLine("After Calling PassByrefOut(Three)");
            Three.Print();
        }
    }
}

TestFunc.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace PassByRef
{
    //Sample 01: A Simple Point Class
    public class Point2D
    {
        private int x;
        private int y;

        public Point2D(int X, int Y)
        {
            x = X;
            y = Y;
        }

        public void Setxy(int Valx, int Valy)
        {
            x = Valx; 
            y = Valy;
        }

        public void Print()
        {
            Console.WriteLine("Content of Point2D :" 
                + x + "," + y);
        }
    }

    static class TestFunc
    {
        //Sample 02: Function Taking Arguments 
        //           Pass By Value
        public static void PassByValFunc(int x)
        {
            //Print Value Received
            Console.WriteLine("PassByValFunc: Receiving x " +
                "by Value. The Value is:{0}", x);

            //Change value of x and Print
            x = 15;
            //Print Value Received
            Console.WriteLine("PassByValFunc: After Changing " +
            "Value, x=" + x);
        }

        //Sample 04: Function Taking Arguments
        //          Pass By Reference (Ref)
        public static void PassByRefFunc(ref int x)
        {
            //Print Value Received
            Console.WriteLine("PassByRefFunc: Receiving x " +
                "by Value. The Value is:{0}", x);

            //Change value of x and Print
            x = 45;

            //Print the changed value
            Console.WriteLine("PassByRefFunc: After Changing " +
            "Value, x=" + x);
        }

        //Sample 06: Function Taking Arguments
        //          Pass By Reference (out)
        public static void PassByrefOut(out int x)
        {
            //Assign value inside the function
            x = 10;

            //Print the changed value
            Console.WriteLine("PassByRefFunc: After Changing " +
            "Value, x=" + x);
        }

        //Sample 08: Pass by Value (Object)
        public static void PassByValFunc(Point2D theObj, int Mode)
        {
            if (Mode == 0)
            {
                theObj.Setxy(7, 8);
                Console.WriteLine("New Value Assigned inside " +
                    "PassByValFunc");
                theObj.Print();
            }
            else if(Mode == 1)
            {
                theObj = new Point2D(100, 75);
                Console.WriteLine("Parameter theObj points " +
                    "to New object inside PassByValFunc");
                theObj.Print();
            }
        }

        //Sample 10: Pass by Reference with ref
        public static void PassByRefFunc(ref Point2D theObj, int Mode)
        {
            if (Mode == 0)
            {
                theObj.Setxy(7, 8);
                Console.WriteLine("New Value Assigned inside " +
                    "PassByValFunc");
                theObj.Print();
            }
            else if (Mode == 1)
            {
                theObj = new Point2D(100, 75);
                Console.WriteLine("Parameter theObj points " +
                    "to New object inside PassByValFunc");
                theObj.Print();
            }
        }

        //Sample 12: Pass by Reference with out
        public static void PassByrefOut(out Point2D theObj)
        {
            theObj = new Point2D(100, 75);
            Console.WriteLine("Parameter theObj points " +
                    "to New object inside PassByValFunc");
                theObj.Print();
        }
    }
}

5. Conclusion

The keywords ref and out deals with how the stack location “Name-Binding” can be done. When we do not specify ref or out keywords, the parameter binds to a location in the called stack and a copy will be performed.

Questions & Answers

    © 2018 sirama

    Comments

      0 of 8192 characters used
      Post Comment

      No comments yet.

      working

      This website uses cookies

      As a user in the EEA, your approval is needed on a few things. To provide a better website experience, owlcation.com uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

      For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at: https://owlcation.com/privacy-policy#gdpr

      Show Details
      Necessary
      HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
      LoginThis is necessary to sign in to the HubPages Service.
      Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
      AkismetThis is used to detect comment spam. (Privacy Policy)
      HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
      HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
      Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
      CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
      Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the googleapis.com or gstatic.com domains, for performance and efficiency reasons. (Privacy Policy)
      Features
      Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
      Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
      Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
      Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
      Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
      VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
      PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
      Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
      MavenThis supports the Maven widget and search functionality. (Privacy Policy)
      Marketing
      Google AdSenseThis is an ad network. (Privacy Policy)
      Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
      Index ExchangeThis is an ad network. (Privacy Policy)
      SovrnThis is an ad network. (Privacy Policy)
      Facebook AdsThis is an ad network. (Privacy Policy)
      Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
      AppNexusThis is an ad network. (Privacy Policy)
      OpenxThis is an ad network. (Privacy Policy)
      Rubicon ProjectThis is an ad network. (Privacy Policy)
      TripleLiftThis is an ad network. (Privacy Policy)
      Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
      Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
      Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
      Statistics
      Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
      ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
      Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)