Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C#, why can't I populate a local variable using its address, then use the variable later?

Consider the following code:

private unsafe void Function()
{
    int length;

    // This line raises error CS1686, "Local 'length' or its members cannot have their address taken and be used inside an anonymous method or lambda expression".
    glGetProgramiv(1, GL_PROGRAM_BINARY_LENGTH, &length);

    FunctionWithLambda(() => Console.WriteLine(length));
}

private void FunctionWithLambda(Action callback)
{
    callback();
}

Note that I'm taking the address of length (a local variable), then using the variable itself (not its address) in a lambda. I understand why a local variable address can't be used in a lambda directly (see Why cannot I pass the address of a variable to an anonymous function?, among other examples), but why can't I use the value of length once assigned (even if that assignment happens to use the & operator)? The official documentation for error CS1686 (https://learn.microsoft.com/bs-latn-ba/dotnet/csharp/misc/cs1686) hasn't clarified this confusion.

My assumption is that this is simply a language limitation, but I'm curious if there's an underlying technical reason I'm missing. Also note I'm not asking how to work around this problem (I know I can easily copy length to another local variable first).

like image 203
Grimelios Avatar asked Dec 07 '21 23:12

Grimelios


People also ask

What does |= mean in C?

The ' |= ' symbol is the bitwise OR assignment operator.

What is '~' in C programming?

In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...

What is an operator in C?

C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.

What is the use of in C?

In C/C++, the # sign marks preprocessor directives. If you're not familiar with the preprocessor, it works as part of the compilation process, handling includes, macros, and more.


1 Answers

The C# specification says the following (my bold):

23.4 Fixed and moveable variables

The address-of operator (§23.6.5) and the fixed statement (§23.7) divide variables into two categories:
Fixed variables and moveable variables.

...snip...

The & operator (§23.6.5) permits the address of a fixed variable to be obtained without restrictions. However, because a moveable variable is subject to relocation or disposal by the garbage collector, the address of a moveable variable can only be obtained using a fixed statement (§23.7), and that address remains valid only for the duration of that fixed statement.

In precise terms, a fixed variable is one of the following:

  • A variable resulting from a simple-name (§12.7.3) that refers to a local variable, value parameter, or parameter array, unless the variable is captured by an anonymous function (§12.16.6.2).
  • .....

So it's explicitly forbidden by the spec. As to why it's forbidden, for that you would have to ask the language designers, but considering how much complexity is involved in capturing variables, it is somewhat logical.

like image 68
Charlieface Avatar answered Oct 28 '22 00:10

Charlieface