Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / November 2007

Tip: Looking for answers? Try searching our database.

initonly array member as an lvalue

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
lee.crabtree - 26 Nov 2007 17:23 GMT
In C#, an array marked 'readonly', as in:

public readonly bool[] array = new bool[8];

would allow individual members of the array to be modified while
protecting the array reference itself from being changed.  That is, I
could do this:

array[0] = false;

but not this:

array = null;

However, it doesn't seem like the 'initonly' keyword in C++/CLI does
exactly the same thing.  If I do something like this:

public ref class Thing
{
public:
   Thing();
   void SetBool();
protected:
   initonly array<bool>^ bArr;
};

Thing::Thing()
{
   bArr = gcnew array<bool>(8);
}

void Thing::SetBool()
{
   bArr[0] = false;
}

I get a compilation error about using an 'initonly' field as an l-
value.  What's the right way to go about this?
Mark Salsbery [MVP] - 26 Nov 2007 20:50 GMT
Your initialization needs to be done in the constructor, even for items in
the array.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

> In C#, an array marked 'readonly', as in:
>
[quoted text clipped - 34 lines]
> I get a compilation error about using an 'initonly' field as an l-
> value.  What's the right way to go about this?
lee.crabtree - 26 Nov 2007 22:01 GMT
Even for an array of value types?  That seems strange.  That still
doesn't explain why the items in the array can't be used as an l-
value.

On Nov 26, 2:50 pm, "Mark Salsbery [MVP]"
<MarkSalsbery[MVP]@newsgroup.nospam> wrote:
> Your initialization needs to be done in the constructor, even for items in
> the array.
[quoted text clipped - 4 lines]
> Mark Salsbery
> Microsoft MVP - Visual C++
Mark Salsbery [MVP] - 27 Nov 2007 00:52 GMT
Here's the error on VS2008:

"error C3893: 'Thing::bArr' : l-value use of initonly data member is only
allowed in an instance constructor of class 'Thing'"

l-value refers to using the variable as the left-value in an assignment -
this is not allowed outside the constructor for initonly variables.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

> Even for an array of value types?  That seems strange.  That still
> doesn't explain why the items in the array can't be used as an l-
[quoted text clipped - 11 lines]
>> Mark Salsbery
>> Microsoft MVP - Visual C++
lee.crabtree - 27 Nov 2007 17:53 GMT
Right, my point is that it doesn't make sense that you can't then
modify entries IN the array.  The C# version of 'initonly', which is
'readonly', merely makes reassigning the REFERENCE illegal.  In
effect, you can't re-new the array or set its reference to null, but
you can set and get entries IN the array.

Am I assuming that 'initonly' should function like 'readonly'?
Mark Salsbery [MVP] - 27 Nov 2007 19:56 GMT
I'm not sure why you think C++ initonly should act like C# readonly.

They aren't even the same keyword.

initonly in C++ does what it says - lets you initialize it and that's it.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

> Right, my point is that it doesn't make sense that you can't then
> modify entries IN the array.  The C# version of 'initonly', which is
[quoted text clipped - 3 lines]
>
> Am I assuming that 'initonly' should function like 'readonly'?
lee.crabtree - 27 Nov 2007 20:34 GMT
I guess the only reason I think 'initonly' and 'readonly' should act
alike is that I found about a dozen articles online stating that they
did.  Serves me right for looking it up, I suppose.
Mark Salsbery [MVP] - 27 Nov 2007 21:48 GMT
Interesting ... I looked up the readonly keyword for C#.  It does indeed
sounds like it should work the same.

Is it a C# bug that allows you to alter members of an array outside a
constructor?

What do the C# experts have to say about that? :)

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

>I guess the only reason I think 'initonly' and 'readonly' should act
> alike is that I found about a dozen articles online stating that they
> did.  Serves me right for looking it up, I suppose.
lee.crabtree - 27 Nov 2007 22:18 GMT
I think it's more likely that the association of 'initonly' to
'readonly' is erroneous in some regard.  As far as I can tell,
'readonly' is only supposed to prevent the REFERENCE from being
overwritten.  In that sense, a List<> marked 'readonly' will allow
adding, removing, and clearing from the list, but setting the list to
null or trying to re-new it would be an error.  In that sense, it's
similar to what I remember (from my long-past days of C++) a 'const'
pointer being used for.  The VALUE is changeable, it's the REFERENCE
that isn't.
Mark Salsbery [MVP] - 28 Nov 2007 01:07 GMT
Right.  I see what you mean, but from the readonly (C#) docs:

"...assignments to the fields introduced by the declaration can only occur
as part of the declaration or in a constructor in the same class."

and

"The readonly keyword is different from the const keyword. A const field can
only be initialized at the declaration of the field. A readonly field can be
initialized either at the declaration or in a constructor. Therefore,
readonly fields can have different values depending on the constructor
used."

That reads to me just like initonly and const in C++.  That's why I wonder
if C# should allow you to change readonly variables later.

It doesn't read like it should just apply to the reference.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

>I think it's more likely that the association of 'initonly' to
> 'readonly' is erroneous in some regard.  As far as I can tell,
[quoted text clipped - 5 lines]
> pointer being used for.  The VALUE is changeable, it's the REFERENCE
> that isn't.
Ben Voigt [C++ MVP] - 28 Nov 2007 16:17 GMT
> Right.  I see what you mean, but from the readonly (C#) docs:
>
> "...assignments to the fields introduced by the declaration can only occur
> as part of the declaration or in a constructor in the same class."

He isn't assigning to the field, he's performing member access on the object
referenced by the field.

It's like having

class C
{
   bool* const p; // p must be assigned in constructor, p[0] can be
assigned anywhere
};

The workaround would be:

ref class C
{
 initonly array<bool>^ b;

 C() : b(gcnew array<bool>(8)) {}
 void doit() { /* b[0] = false; */ array<bool>^ bprime; bprime[0] =
false; }
};

> and
>
[quoted text clipped - 20 lines]
>> pointer being used for.  The VALUE is changeable, it's the REFERENCE
>> that isn't.
Ben Voigt [C++ MVP] - 28 Nov 2007 16:20 GMT
>> Right.  I see what you mean, but from the readonly (C#) docs:
>>
[quoted text clipped - 22 lines]
> false; }
> };

oops, missed the initialization of bprime, should have been

void doit() { /* b[0] = false; */ array<bool>^ bprime = b; bprime[0] =
false; }
lee.crabtree - 28 Nov 2007 16:43 GMT
I can't believe I didn't think to do that from the beginning.  Even
so, this seems like really strange behavior.
Mark Salsbery [MVP] - 28 Nov 2007 17:35 GMT
Right.  You can get around const with casts too.
But why would const or initonly be used on variables one wants to change
later?

I guess I missed the original point of the thread.
My point was just that initonly works as documented.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

>>> Right.  I see what you mean, but from the readonly (C#) docs:
>>>
[quoted text clipped - 27 lines]
> void doit() { /* b[0] = false; */ array<bool>^ bprime = b; bprime[0] =
> false; }
Ben Voigt [C++ MVP] - 28 Nov 2007 19:02 GMT
> Right.  You can get around const with casts too.
> But why would const or initonly be used on variables one wants to change
> later?

What cast?  There is no cast.

The reference marked as initonly is not being changed, it always holds the
address of the same object.  The data within that object could change.  This
could, for example, allow a gc optimization because the lifetime of the two
objects are equal and therefore the objects needn't be tracked separately.

> I guess I missed the original point of the thread.
> My point was just that initonly works as documented.

Perhaps, but it functions differently than native C++ const or C# readonly,
and the behavior makes no sense.  If an initonly reference is supposed to
point to an immutable object, then it should carry the initonly attribute on
the referred-to type and not be lost without a const_cast.  It then would
look like this:

array<initonly bool>^ b;

But that makes no sense, because it raises the question "Which constructor
is allowed to change the value?"

If you have

array<bool>^ initonly b;

then it is only natural to be able to

b[0] = false;

> Mark
>
[quoted text clipped - 30 lines]
>> void doit() { /* b[0] = false; */ array<bool>^ bprime = b; bprime[0] =
>> false; }
Mark Salsbery [MVP] - 28 Nov 2007 21:04 GMT
>> Right.  You can get around const with casts too.
>> But why would const or initonly be used on variables one wants to change
[quoted text clipped - 13 lines]
> Perhaps, but it functions differently than native C++ const or C#
> readonly,

Right.  My original point was that comparing two different keywords from two
different languages was irrelevant, no matter how many articles or other
people say they are the same..

> and the behavior makes no sense.

Now that I'm following the theme of the thread, I agree 100% :)

Thanks Ben!
Mark

>If an initonly reference is supposed to point to an immutable object, then
>it should carry the initonly attribute on the referred-to type and not be
[quoted text clipped - 14 lines]
>
>> Mark

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.