tags:

views:

101

answers:

2

So I am Reflector-ing some framework 2.0 code and end up with the following deconstruction

fixed (void* voidRef3 = ((void*) &_someMember))
{
...
}

This won't compile due to 'The right hand side of a fixed statement assignment may not be a cast expression'

I understand that Reflector can only approximate and generally I can see a clear path but this is a bit outside my experience.

Question: what is Reflector trying to describe to me?

Update:

Am also seeing the following

fixed (IntPtr* ptrRef3 = ((IntPtr*) &this._someMember))

Update:

So, as Mitch says, it is not a bitwise operator, but an addressOf operator.

Question is now:

fixed (IntPtr* ptrRef3 = &_someMember)

fails with an 'Cannot implicitly convert type 'xxx*' to 'System.IntPtr*'. An explicit conversion exists (are you missing a cast?)' compilation error.

So I seemed to be damned if I do and damned if I dont. Any ideas?

UPDATE:

I think i have it figured. By chance I went back to the expression that was using void* and removed the casts and VS stopped complaining and since I gathered from the participants in this conversation that void* and intptr* are equivalent I simply swapped them out, resulting in this:

fixed (void* ptrRef3 = &_someMember)

and VS stopped complaining. Can someone verify that

fixed (void* ptrRef3 = &_someMember)

is equivalent to

fixed (IntPtr* ptrRef3 = &_someMember)

?

+2  A: 

It is taking the address of _someMember and casting it to (void *) (i.e. a pointer address), and then setting a location to that address.

The fixed statement 'pins' the object, and prevents the GC from moving it around.

The '&' used in that context is the 'Address Of' operator, not Bitwise And.

In response to updated question:

Have you tried:

fixed (void* voidRef3 = &_someMember) 
{ 
... 
}
Mitch Wheat
Sky Sanders
It is not the bitwise operator when used that way; it is the 'address of' operator (same as in C and C++)
Mitch Wheat
I suspected as much. So let me adjust the question. Thanks and sorry for the moving target.
Sky Sanders
OK, +1 and a check for answering my question as written. I guess what I was really after was a hint on how to express the same in compilable form. Can you help me along with that?
Sky Sanders
A: 

Responding to your last comment: does this work for you?

fixed (IntPtr* ptrRef3 = (IntPtr *) &_someMember)

Edit

I'm not sure what you mean

that is effectively what reflector gave me

The error you mention seems quite clear: it can explicitly convert from (void *) to (IntPtr *) if you ask. My example asks, yours doesn't.

Are you really getting the same error message when you insert the (IntPtr *)?

Another Edit

Can someone verify that

fixed (void* ptrRef3 = &_someMember)

is equivalent to

fixed (IntPtr* ptrRef3 = &_someMember)

First of all: yes, they're equivalent.

Second of all: I've been thinking about what all this means. I think the decompiler figures it doesn't know enough to create a movable reference to _someMember, and so can't leave it to the C# runtime to manage it. To cope with this, it uses fixed to disable garbage collection for that memory, leaving it to you to tell the runtime when it's safe to deallocate.

Therefore this is not code you should keep around: as soon as you figure out the real meaning and lifespan of that bit of data, rewrite it to use regular (garbage collected) variables.

egrunin
thanks for the response but that is effectively what reflector gave me and it gives the compilation error I listed. Unless the whitespace between `IntPtr` and `*` is significant? So apparently I do not know how to express the cast in a way that the compiler finds pleasure with. I think therein lies the rub.
Sky Sanders
Reflector (http://www.red-gate.com/products/reflector/) is a .net decompilation tool that generates code from IL. Generally, it outputs compilable code but there are edge cases in which it does not have the smarts to construct the proper C# from the IL. And in those cases, I am usually able to infer the intention. This seems to be one that, obviously, I am at a loss on how to express properly in C#. And, yes, the example you give is effectively the same as the second snippet in my question that gives the same compilation error.
Sky Sanders
It is a given that this 'intent' is expressable in C# as the original source is C#, but the decompilation tool has done me no favors in this instance. I am no C# guru, but I, like you, have been pushing bits for several decades and it irks me when I get stumped by sytax. ;-)
Sky Sanders
@egrunin - I seem to have arrived at a solution. Would you mind taking a look?
Sky Sanders