Skip to content

How to Resolve Error "CS0211: Cannot take the address of the given expression" in C#

Fix CS0211 errors in C# by understanding why literals, constants, properties, and method calls can't be addressed with & and how to use local variables or fields instead.

The Compiler Error CS0211 is a syntax error specific to Unsafe Code and pointer arithmetic. The message reads: "Cannot take the address of the given expression".

In C#, the address-of operator (&) retrieves the memory location of a variable. To have a memory location, an item must be a Variable (a storage location like a local variable or field). You cannot take the address of a Value (like a literal number), a Constant, or a Property (which is actually a method call).

This guide explains why certain expressions do not have accessible addresses and how to fix your code to use pointers correctly.

Understanding Addressable Expressions

To use &x, x must reside in a stable location in memory (stack or heap) that you are allowed to point to.

  • Valid Targets: Local variables (int x), Fields (obj.field), and array elements (arr[0]).
  • Invalid Targets (CS0211):
    • Literals: &10 (The number 10 doesn't have a permanent address; it's just a value).
    • Constants: const int X (These are substituted at compile-time; they aren't variables).
    • Properties: &obj.Prop (Properties are methods get_Prop() in disguise; you can't take the address of a method result directly).
    • Method Calls: &GetVal() (The return value is temporary and lives on the stack only for a nanosecond).

Scenario 1: Constants and Literals

You cannot point to a raw number or a constant variable because constants are often embedded directly into the bytecode instructions rather than stored in a specific memory slot.

Example of error

public class Program
{
    public const int MaxValue = 100;

    unsafe static void Main()
    {
        // ⛔️ Error CS0211: Cannot take the address of the given expression.
        // You cannot take the address of a literal number.
        int* ptr1 = &50;

        // ⛔️ Error CS0211: Constants are not variables.
        int* ptr2 = &MaxValue; 
    }
}

Solution: Use a Local Variable

Assign the value to a local variable first. A local variable has a distinct address on the stack.

public class Program
{
    unsafe static void Main()
    {
        // 1. Assign literal/constant to a variable
        int number = 50;

        // 2. Take the address of the variable
        // ✅ Correct: 'number' lives on the stack, so we can point to it.
        int* ptr = &number;
        
        System.Console.WriteLine(*ptr); // Output: 50
    }
}

Scenario 2: Properties and Indexers

This is the most common cause of CS0211. Properties look like fields, but they are actually method calls (get and set). You cannot take the address of a method call's result because the result is a temporary copy, not the original storage.

Example of error

public struct Point
{
    // This is an Auto-Property (Methods get_X and set_X)
    public int X { get; set; }
}

public class Program
{
    unsafe static void Main()
    {
        Point p = new Point();
        p.X = 10;

        // ⛔️ Error CS0211: Cannot take the address of 'p.X'
        // 'p.X' is a property access, effectively 'p.get_X()'.
        int* ptr = &p.X; 
    }
}

Solution: Use a Field or a Copy

If you own the class/struct, change the Property to a Field. If you cannot change the class, copy the value to a local variable.

Option A: Use a Field (If possible)

public struct Point
{
    // ✅ Correct: Fields represent raw storage.
    public int X; 
}

// &p.X is now valid.

Option B: Use a Local Copy (If using Properties)

unsafe static void Main()
{
    Point p = new Point();
    p.X = 10;

    // 1. Copy the value to a local variable
    int tempX = p.X;

    // 2. Point to the copy
    // ✅ Correct
    int* ptr = &tempX;
}

Scenario 3: Method Return Values

Similar to properties, you cannot take the address of a value returned by a function call.

Example of error

public class Calculator
{
    public static int GetNumber() => 42;

    unsafe static void Main()
    {
        // ⛔️ Error CS0211: Cannot take the address of a method call.
        int* ptr = &GetNumber();
    }
}

Solution

Assign the return value to a variable.

unsafe static void Main()
{
    // ✅ Correct: Store the result first
    int result = Calculator.GetNumber();
    int* ptr = &result;
}

Conclusion

CS0211 ensures you only point to valid, addressable memory locations.

  1. Identify the Target: Are you trying to use & on a literal (5), a constant, or a property (obj.Prop)?
  2. Understand Properties: Remember that obj.Property is code to get a value, not the value's location itself.
  3. The Universal Fix: Introduce a local variable. Assign your value to int x, and then use &x.
Navigation