C# compiler bug

  • Thread starter Thread starter Subramaniyan Neelagandan
  • Start date Start date
S

Subramaniyan Neelagandan

The following program outputs False rather than True.


using System;

namespace Test

{

public struct V

{

public bool booleanV;

public void setBoolean(bool _value)

{

booleanV = _value;

}

}

public class C

{

public readonly V Value;

}

public class StructBug

{

static public void Main(string[] args)

{

C c = new C();

c.Value.setBoolean(true);

Console.WriteLine(c.Value.booleanV);

Console.Read();

}

}

}
 
The following program outputs False rather than True.

And that is correct. It's a programmer bug, not a compiler bug.
Investigate the difference between struct and class.
 
Subramaniyan Neelagandan said:
The following program outputs False rather than True.

And indeed it should.

From the ECMA C# spec, section 14.5.4, Member Access:
(applicable sections only):

A member-access of the form E.I, where E is a primary-expression or a
predefined-type and I is an identifier, is evaluated and classified as
follows:

If E is a property access, indexer access, variable, or value, the type
of which is T, and a member lookup (§14.3) of I in T produces a match,
then E.I is evaluated and classified as follows:

If T is a class-type and I identifies an instance field of that class-
type:

[...]

Otherwise, if the field is readonly and the reference occurs outside an
instance constructor of the class in which the field is declared, then
the result is a value, namely the value of the field I in the object
referenced by E.


So, due to it being a read-only field, the result of the expression
c.Value is the value of c.Value, not a variable. Changing the data in
that value doesn't change the data in c.Value, as V is a value type.
 
So, due to it being a read-only field, the result of the expression
c.Value is the value of c.Value, not a variable. Changing the data in
that value doesn't change the data in c.Value, as V is a value type.

You will also get a compiler error if you write the more obvious
operation: c.Value.booleanV = true;

Using a set method for a struct field is a rather ingenuous method to
sneak bugs into a C# program, I have to admit... maybe the next
version of the C# compiler could check for that?
 
Christoph Nahr said:
And that is correct. It's a programmer bug, not a compiler bug.
Investigate the difference between struct and class.

Well, in particular, how that interacts with the fact that the Value
variable is readonly. If you make it writable, it prints True.
 
Hi,

Which spec you are talking about? I have version 1.2 in word format as well
as in my MSDN library. Both are talking about Enum.

So, could you point me to the spec you are talking about?

Thanks
SN


Subramaniyan Neelagandan said:
The following program outputs False rather than True.

And indeed it should.

From the ECMA C# spec, section 14.5.4, Member Access:
(applicable sections only):

A member-access of the form E.I, where E is a primary-expression or a
predefined-type and I is an identifier, is evaluated and classified as
follows:

If E is a property access, indexer access, variable, or value, the type
of which is T, and a member lookup (§14.3) of I in T produces a match,
then E.I is evaluated and classified as follows:

If T is a class-type and I identifies an instance field of that class-
type:

[...]

Otherwise, if the field is readonly and the reference occurs outside an
instance constructor of the class in which the field is declared, then
the result is a value, namely the value of the field I in the object
referenced by E.


So, due to it being a read-only field, the result of the expression
c.Value is the value of c.Value, not a variable. Changing the data in
that value doesn't change the data in c.Value, as V is a value type.
 
Hi,

I found the section. It is 7.5.4.

Thanks



Subramaniyan Neelagandan said:
The following program outputs False rather than True.

And indeed it should.

From the ECMA C# spec, section 14.5.4, Member Access:
(applicable sections only):

A member-access of the form E.I, where E is a primary-expression or a
predefined-type and I is an identifier, is evaluated and classified as
follows:

If E is a property access, indexer access, variable, or value, the type
of which is T, and a member lookup (§14.3) of I in T produces a match,
then E.I is evaluated and classified as follows:

If T is a class-type and I identifies an instance field of that class-
type:

[...]

Otherwise, if the field is readonly and the reference occurs outside an
instance constructor of the class in which the field is declared, then
the result is a value, namely the value of the field I in the object
referenced by E.


So, due to it being a read-only field, the result of the expression
c.Value is the value of c.Value, not a variable. Changing the data in
that value doesn't change the data in c.Value, as V is a value type.
 
Also if I strongly name an assembly, will it reference the recompiled
component once it's recompiled, or will it always keep the one its reference
was initially set to?
 
I don't believe that this has something to do with strong name or not.
But if you've declared the variable as const then the constant would be
hardbakened into all referencing assembly and changing itf value when
recompiling would not affect other assemblies.
But if you have readonly variables, changing them changes them in all
referencing assemblies.
 
Back
Top