Skip to main content

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

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;
}
warning

Important: If you modify *ptr in Option B, you are modifying tempX, not p.X. If you need to modify the property via a pointer, this workaround won't reflect changes back to the object.

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.