C++/CLI quirk passing properties as reference parameters

D

David Lowndes

The following example illustrates something that's taken me a while to
suss out (debugging someone else's code :( )...

The crux is that the code compiles cleanly at W4, and the issue is
that I'm passing a property by reference to a function that's trying
to modify it.

Needless to say the result isn't what was intended as the property
doesn't get modified.

So... ought the compiler to allow this?
At the very least I'd hope to have a warning message.

#include "stdafx.h"
using namespace System;

ref struct MyStruct
{
int m_i1;
property int m_i2;
};

void f1( int % i )
{
i++;
}

int main(array<System::String ^> ^/*args*/)
{
MyStruct s;

s.m_i1 = 1;
s.m_i2 = 2;

Console::WriteLine(L"m_i1 is:" + s.m_i1.ToString() + " m_i2
is: " + s.m_i2.ToString() );

f1( s.m_i1 );
f1( s.m_i2 );

Console::WriteLine(L"m_i1 is:" + s.m_i1.ToString() + " m_i2
is: " + s.m_i2.ToString() );
return 0;
}

Dave Lowndes
 
B

Ben Voigt

David Lowndes said:
The following example illustrates something that's taken me a while to
suss out (debugging someone else's code :( )...

The crux is that the code compiles cleanly at W4, and the issue is
that I'm passing a property by reference to a function that's trying
to modify it.

Needless to say the result isn't what was intended as the property
doesn't get modified.

So... ought the compiler to allow this?
At the very least I'd hope to have a warning message.

As you say, it ought to be generating a warning such as "passing temporary
by non-const reference" or "taking address of temporary", which I've indeed
seen on some of my own code before.

Does the code use pragma warning anywhere?
 
D

David Lowndes

Does the code use pragma warning anywhere?

That particular code was a VS2005 generated C++/CLI console project, I
set W4 in the project settings to see if it would identify an issue -
it didn't :(

I can't see anything in the generated sources that would drop the
warning level.

Dave
 
B

Ben Voigt

David Lowndes said:
That particular code was a VS2005 generated C++/CLI console project, I
set W4 in the project settings to see if it would identify an issue -
it didn't :(

I can't see anything in the generated sources that would drop the
warning level.

Dave

Looks like an issue because .NET has no concept of a constant reference.

Part of your problem is that you're accepting a tracking reference. Since
int is a value type, you can use & instead, which works as expected and
generates an error.

void f1(int% ri)
{
ri = 0;
}

void f2(int& ri)
{
ri = 0;
}

int get(void)
{
return 10;
}

int main(void)
{
f1(get()); // no error
f2(get()); // error
}

However, the documentation says that % should work as well (See article: How
to: Write Template Functions that Take Native, Value, or Reference
Parameters), so this looks like a genuine bug. I think we should look at
the generated MSIL, I suspect that implicit boxing is taking place.
..method assembly static int32 main() cil managed
{
.maxstack 1
.locals (
[0] int32 num1)
L_0000: call int32 <Module>::get()
L_0005: stloc.0
L_0006: ldloca.s num1
L_0008: call void <Module>::f1(int32&)
L_000d: ldc.i4.0
L_000e: ret
}

Nope, no boxing. Just a temporary passed by non-const reference. Seems to
be a result of Microsoft's choice not to implement const safety in managed
code. There's no way the compiler can know from the function prototype
whether the argument will be changed. Seems like it should then be a
warning instead of an error.

However, even adding the OutAttribute on the parameter, the code doesn't
generate even a warning although it clearly should be an error to use a
temporary as an out-only parameter.

File a bug report and I'll vote for and validate it, here's your minimal
repro code (compile with /clr:safe):

void f1([System::Runtime::InteropServices::Out] int% ri)
{
ri = 0;
}

int get( void )
{
return 10;
}

int main(void)
{
f1(get());
}
 
B

Ben Voigt

David Lowndes said:
Resolved (Won't Fix) with no comments to explain why or if they ever
will consider it :(

Some of the folks on there seem genuinely interested in making the products
better, while there are at least a few only interested in improving their
statistics (bugs closed/week)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top