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 methodsget_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).
- Literals:
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;
}
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.
- Identify the Target: Are you trying to use
&on a literal (5), a constant, or a property (obj.Prop)? - Understand Properties: Remember that
obj.Propertyis code to get a value, not the value's location itself. - The Universal Fix: Introduce a local variable. Assign your value to
int x, and then use&x.