Initonly - but it is not (bug?) VC++ 2008/CLR

A

Armin Zingler

Hi,

could anyone please tell me why I get a compile error (C3893) in the last
line? Error message is (translated):

"'Frame::Items': The usage of the L value of an initonly data member is only
allowed in an instance constructor of the Frame class."


using namespace System;
using namespace System::Collections::Generic;

public ref class TVB abstract
{
public:
IO::Stream^ s;
};

public ref class Frame
{
public:
initonly List<TVB^>^ Items;

Frame(): Items(gcnew List<TVB^>){};
};

int main()
{
Frame^ f = gcnew Frame();

f->Items[0]->s = gcnew IO::MemoryStream(); //<<<<<<<< C3893
};


The point is, I do _not_ assign anything to f->Items. I assign something to
a member of an Item of the list. The member is _not_ initonly. Therefore, I
don't see a reason for the error. If I split the line up in two lines -
which shouldn't make any difference in this case - it does work:

TVB^ tmp = f->Items[0];
tmp->s = gcnew System::IO::MemoryStream();

Is this a bug or do I overlook anything?

(I do know that the code wouldn't work because I wouldn't have added
anything to the generic list, but even if I did it doesn't compile...)


Armin
 
B

Ben Voigt [C++ MVP]

Armin said:
Hi,

could anyone please tell me why I get a compile error (C3893) in the
last line? Error message is (translated):

"'Frame::Items': The usage of the L value of an initonly data member
is only allowed in an instance constructor of the Frame class."


using namespace System;
using namespace System::Collections::Generic;

public ref class TVB abstract
{
public:
IO::Stream^ s;
};

public ref class Frame
{
public:
initonly List<TVB^>^ Items;

Frame(): Items(gcnew List<TVB^>){};
};

int main()
{
Frame^ f = gcnew Frame();

f->Items[0]->s = gcnew IO::MemoryStream(); //<<<<<<<< C3893
};


The point is, I do _not_ assign anything to f->Items. I assign
something to a member of an Item of the list. The member is _not_
initonly. Therefore, I don't see a reason for the error. If I split
the line up in two lines - which shouldn't make any difference in
this case - it does work:
TVB^ tmp = f->Items[0];
tmp->s = gcnew System::IO::MemoryStream();

Is this a bug or do I overlook anything?

You're right, it appears to be a bug. The workaround is quite simple
(introduce a temporary thus):

List<TVB^>^ It = f->Items;

It[0]->s = gcnew IO::MemoryStream();


Or what I would actually recommend is making that member use stack
semantics.
 
A

Armin Zingler

Ben Voigt said:
The point is, I do _not_ assign anything to f->Items. I assign
something to a member of an Item of the list. The member is _not_
initonly. Therefore, I don't see a reason for the error. If I
split the line up in two lines - which shouldn't make any
difference in this case - it does work:
TVB^ tmp = f->Items[0];
tmp->s = gcnew System::IO::MemoryStream();

Is this a bug or do I overlook anything?

You're right, it appears to be a bug. The workaround is quite
simple (introduce a temporary thus):

List<TVB^>^ It = f->Items;

It[0]->s = gcnew IO::MemoryStream();


Or what I would actually recommend is making that member use stack
semantics.

Sorry for the late answer and thanks for your reply. I'll file a bug report
@ MSFT connect.


Armin
 

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