R# 4.0.478 possible lambda bug?

Apologies if this isn't a bug - I'm still getting used to lambdas :)

The following code produces blue squigglies under the "invalid"
parameter to the Array.Exists call (with a message of "Access to
modified closure"). Does the code have a problem or is it R#?

// check whether path is valid
char[] invalid = Path.GetInvalidPathChars();
if( Array.Exists( dirName.ToCharArray(),
c => Array.Exists( invalid, ic => c == ic ) ) )
{
dirName = "invalid character in path";
}
// check whether file name is valid
invalid = Path.GetInvalidFileNameChars();
if( Array.Exists( fileName.ToCharArray(),
c => Array.Exists( invalid, ic => c == ic ) ) )
{
fileName = "invalid character in file name";
}

Yours,
Morten

3 comments
Comment actions Permalink

Hello,

The following code produces blue squigglies under the "invalid"
parameter to the Array.Exists call (with a message of "Access to
modified closure"). Does the code have a problem or is it R#?


It's just an "Attention!" sign. So, the code has a potential problem you
should be aware of. In this particular case, the problem will not manifest
itself.

// check whether path is valid
char[] invalid = Path.GetInvalidPathChars();
if( Array.Exists( dirName.ToCharArray(),
c => Array.Exists( invalid, ic => c == ic ) ) )
{
dirName = "invalid character in path";
}
// check whether file name is valid
invalid = Path.GetInvalidFileNameChars();
if( Array.Exists( fileName.ToCharArray(),
c => Array.Exists( invalid, ic => c == ic ) ) )
{
fileName = "invalid character in file name";
}


R# cannot tell whether the Array::Exists function executes the lambda immediately
or stores for the later execution. If the former is true (which is, actually,
as it is), then the code works as you expect it to work. In the latter case,
though, if the execution is postponed, all of the lambdas would execute on
the same value of the "invalid" var. Like this:

• Set initial "invalid" value.
• Create the first lambda.
• Set the new "invalid" value.
• Create the second lambda.
• …
• Execute both lambdas.

In this case, the new "invalid" value is actually used in both lambdas, even
though the code looks like they're different.

This hidden fact is exposed by the R#'s highlighting.

A common case for this bug is advising some event in a loop using an anonimous
delegate or lambda that uses the loop variable in its body.


Serge Baltic
JetBrains, Inc — http://www.jetbrains.com
“Develop with pleasure!”


0
Comment actions Permalink

Hi Serge,

>> The following code produces blue squigglies under the "invalid"
>> parameter to the Array.Exists call (with a message of "Access to
>> modified closure"). Does the code have a problem or is it R#?


It's just an "Attention!" sign. So, the code has a potential problem you
should be aware of. In this particular case, the problem will not
manifest itself.

In this case, the new "invalid" value is actually used in both lambdas,
even though the code looks like they're different.


Makes sense. It would be great if there was a way to selectively turn
off warnings like this (I prefer to see no squigglies and get stressed
when I see one :)

As far as I can see it should be safe to turn them off for the Array
methods, as they are all evaluated right away. A more flexible solution
would be to allow me to right-click and disable the warning, but this
will also quickly become tedious.

Some kind of global repository for information such as this would make
the most sense, but I'm sure there are lots of edge cases making this
more difficult than it sounds.

This hidden fact is exposed by the R#'s highlighting.

A common case for this bug is advising some event in a loop using an
anonimous delegate or lambda that uses the loop variable in its body.


Yes, I can see how that might pose a problem. Thanks for the detailed
response.

Yours,
Morten

0
Comment actions Permalink

Hello,

Makes sense. It would be great if there was a way to selectively turn
off warnings like this (I prefer to see no squigglies and get stressed
when I see one :)


It's only possible to turn off the warning altogether, for all the cases,
but probably it should be done more selectively for various cases, yes. I've
heard some talk about changing this warning to a highlighting, so that you
could take care when lambding over mutable variables.

In your code sample, maybe it would be reasonable to use different local
variables in those two calls, one variable per call. Logially, your "invalid"
variable is immutable, even though it's reused, so it's like "immutable,
but for two values".


Serge Baltic
JetBrains, Inc — http://www.jetbrains.com
“Develop with pleasure!”


0

Please sign in to leave a comment.