admin管理员组

文章数量:1025512

I have a function with following signature

State MoveForward(in Path path);

Path is a ref struct
State is also a ref struct with just integer.

Now I have another helper function

bool TryMoveForward(in Path path, ref State state)
{
    // which does something like:
    state = MoveForward(path); // "line A"
    return !state.IsEnd(); // IsEnd determined by integer != -1
}

At the "line A" I am getting the error CS8347: Cannot use a result of 'MoveForward' in this context because it may expose variables referenced by parameter 'path' outside of their declaration scope.

But I think this shouldn't be the case or atleast compiler can be smart enough to avoid throwing this error for few reasons:

  1. State is created just with integers (Compiler can look into the usage of path). There is no reference exposed from "path"
  2. "State" is a ref struct which doesn't carry any "ref" to escape with.

How can I make compiler not complain about this?

I don't understand whether it is a problem of assigning something to ref State state or passing the path to in parameter.

If I remove in in MoveForward the error goes away. I want to keep the "in"

If I split the line, I don't have any way to avoid the error. eg:

    var result = MoveForward(path); // "line A"
    state = result;
    return !state.IsEnd(); // IsEnd determined by integer != -1

Getting CS8352: Cannot use variable 'result' in this context because it may expose referenced variables outside of their declaration scope.

state has its own memory in stack and result should be able to be copied to state similar to single line statement.

I have a function with following signature

State MoveForward(in Path path);

Path is a ref struct
State is also a ref struct with just integer.

Now I have another helper function

bool TryMoveForward(in Path path, ref State state)
{
    // which does something like:
    state = MoveForward(path); // "line A"
    return !state.IsEnd(); // IsEnd determined by integer != -1
}

At the "line A" I am getting the error CS8347: Cannot use a result of 'MoveForward' in this context because it may expose variables referenced by parameter 'path' outside of their declaration scope.

But I think this shouldn't be the case or atleast compiler can be smart enough to avoid throwing this error for few reasons:

  1. State is created just with integers (Compiler can look into the usage of path). There is no reference exposed from "path"
  2. "State" is a ref struct which doesn't carry any "ref" to escape with.

How can I make compiler not complain about this?

I don't understand whether it is a problem of assigning something to ref State state or passing the path to in parameter.

If I remove in in MoveForward the error goes away. I want to keep the "in"

If I split the line, I don't have any way to avoid the error. eg:

    var result = MoveForward(path); // "line A"
    state = result;
    return !state.IsEnd(); // IsEnd determined by integer != -1

Getting CS8352: Cannot use variable 'result' in this context because it may expose referenced variables outside of their declaration scope.

state has its own memory in stack and result should be able to be copied to state similar to single line statement.

Share Improve this question edited Nov 18, 2024 at 11:12 Vivek MVK asked Nov 18, 2024 at 9:45 Vivek MVKVivek MVK 1,17910 silver badges19 bronze badges 6
  • 1 I cannot reproduce this. Did I misunderstand something? – Sweeper Commented Nov 18, 2024 at 10:01
  • @Sweeper, made a small change in your code to use "state" to update after calling MoveForward – Vivek MVK Commented Nov 18, 2024 at 10:22
  • State looks like an out rather than a ref in TryMoveForward() – Jimi Commented Nov 18, 2024 at 11:20
  • @Jimi, some code are redacted. TryMoveForward also uses input from state – Vivek MVK Commented Nov 18, 2024 at 12:14
  • The State returned from MoveForward() is then what? Based on the code posted here, I assume bool TryMoveForward(in Path path, out State state) would compile. Maybe something actually relevant is missing? – Jimi Commented Nov 18, 2024 at 13:36
 |  Show 1 more comment

1 Answer 1

Reset to default 2

Based on this explanations https://github/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md#keywords-vs-attributes

Opt out is a keyword (scoped) but the opt in is an attribute ([UnscopedRef]). So in your case you must defined it as scoped:

State MoveForward(scoped in Path path)

I have a function with following signature

State MoveForward(in Path path);

Path is a ref struct
State is also a ref struct with just integer.

Now I have another helper function

bool TryMoveForward(in Path path, ref State state)
{
    // which does something like:
    state = MoveForward(path); // "line A"
    return !state.IsEnd(); // IsEnd determined by integer != -1
}

At the "line A" I am getting the error CS8347: Cannot use a result of 'MoveForward' in this context because it may expose variables referenced by parameter 'path' outside of their declaration scope.

But I think this shouldn't be the case or atleast compiler can be smart enough to avoid throwing this error for few reasons:

  1. State is created just with integers (Compiler can look into the usage of path). There is no reference exposed from "path"
  2. "State" is a ref struct which doesn't carry any "ref" to escape with.

How can I make compiler not complain about this?

I don't understand whether it is a problem of assigning something to ref State state or passing the path to in parameter.

If I remove in in MoveForward the error goes away. I want to keep the "in"

If I split the line, I don't have any way to avoid the error. eg:

    var result = MoveForward(path); // "line A"
    state = result;
    return !state.IsEnd(); // IsEnd determined by integer != -1

Getting CS8352: Cannot use variable 'result' in this context because it may expose referenced variables outside of their declaration scope.

state has its own memory in stack and result should be able to be copied to state similar to single line statement.

I have a function with following signature

State MoveForward(in Path path);

Path is a ref struct
State is also a ref struct with just integer.

Now I have another helper function

bool TryMoveForward(in Path path, ref State state)
{
    // which does something like:
    state = MoveForward(path); // "line A"
    return !state.IsEnd(); // IsEnd determined by integer != -1
}

At the "line A" I am getting the error CS8347: Cannot use a result of 'MoveForward' in this context because it may expose variables referenced by parameter 'path' outside of their declaration scope.

But I think this shouldn't be the case or atleast compiler can be smart enough to avoid throwing this error for few reasons:

  1. State is created just with integers (Compiler can look into the usage of path). There is no reference exposed from "path"
  2. "State" is a ref struct which doesn't carry any "ref" to escape with.

How can I make compiler not complain about this?

I don't understand whether it is a problem of assigning something to ref State state or passing the path to in parameter.

If I remove in in MoveForward the error goes away. I want to keep the "in"

If I split the line, I don't have any way to avoid the error. eg:

    var result = MoveForward(path); // "line A"
    state = result;
    return !state.IsEnd(); // IsEnd determined by integer != -1

Getting CS8352: Cannot use variable 'result' in this context because it may expose referenced variables outside of their declaration scope.

state has its own memory in stack and result should be able to be copied to state similar to single line statement.

Share Improve this question edited Nov 18, 2024 at 11:12 Vivek MVK asked Nov 18, 2024 at 9:45 Vivek MVKVivek MVK 1,17910 silver badges19 bronze badges 6
  • 1 I cannot reproduce this. Did I misunderstand something? – Sweeper Commented Nov 18, 2024 at 10:01
  • @Sweeper, made a small change in your code to use "state" to update after calling MoveForward – Vivek MVK Commented Nov 18, 2024 at 10:22
  • State looks like an out rather than a ref in TryMoveForward() – Jimi Commented Nov 18, 2024 at 11:20
  • @Jimi, some code are redacted. TryMoveForward also uses input from state – Vivek MVK Commented Nov 18, 2024 at 12:14
  • The State returned from MoveForward() is then what? Based on the code posted here, I assume bool TryMoveForward(in Path path, out State state) would compile. Maybe something actually relevant is missing? – Jimi Commented Nov 18, 2024 at 13:36
 |  Show 1 more comment

1 Answer 1

Reset to default 2

Based on this explanations https://github/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md#keywords-vs-attributes

Opt out is a keyword (scoped) but the opt in is an attribute ([UnscopedRef]). So in your case you must defined it as scoped:

State MoveForward(scoped in Path path)

本文标签: cCS8347CS8352 with quotref structquot and quotinquotquotrefquot parameterStack Overflow