CSharp/C# >> Why aren't arrays of constants equivalent to constant expressions?

by JJ Feminella » Thu, 08 Jan 2004 23:29:46 GMT

This is a multi-part message in MIME format.


This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a constant declarator [involve] constant expressions'. A constant expression is defined as 'an expression that can be fully evaluated at compile-time ... Therefore, the only possible values for constants of reference types are string and null.'

In other words, constant arrays of any otherwise constant type are not legal C#. I understand that this is the case because string[] is really of type System.Array, which is an object (also a dead giveaway since we used the new operator). Fine. I'll get the next best thing and use static readonly in place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon", "Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant array? Any help would be greatly appreciated. Thanks.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1276" name=GENERATOR>
<STYLE></STYLE>
</HEAD><FONT face=Arial><FONT size=2>
<BODY>
<DIV><FONT face=SimSun color=#008000>This statement is legal C#:</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>  <STRONG>public const
string</STRONG> day = "Sunday";</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>but this statement is not:</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>  <STRONG>public const
string[]</STRONG> days = <STRONG>new string[]</STRONG> { "Sun", "Mon", "Tue"
};</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>The C# Programmer's Reference
specifies that 'the only valid values of a constant declarator [involve]
constant expressions'. A constant expression is defined as 'an expression that
can be fully evaluated at compile-time ... Therefore, the only possible values
for constants of reference types are string and null.'</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>In other words, constant arrays of any
otherwise constant type are not legal C#. I understand that this is the case
because string[] is really of type System.Array, which is an object (also a dead
giveaway since we used the <STRONG>new</STRONG> operator). Fine. I'll get the
next best thing and use <STRONG>static readonly</STRONG> in place of where I'd
like to use <STRONG>const</STRONG>. The statement becomes:</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>  <STRONG>public static readonly
string[]</STRONG> days = <STRONG>new string[]</STRONG> { "Sun", "Mon", "Tue"
};</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>and the compiler's happy.</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>But now if I run FxCop on an assembly
containing this statement, it gets mad at me:</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>  '... Fields that are arrays should
not be readonly'</FONT></DIV>
<DIV><FONT face=SimSun color=#008000>  'Make the array 'const' to truly
protect its contents.'</FONT></DIV>
<DIV><FONT face=SimSun color=#008000></FONT> </DIV>
<DIV><FONT face=SimSun color=#008000>What the heck? Am I missing something here?
How do you declare a constant array? Any help would be greatly appreciated.
Thanks.</FONT></DIV></BODY></HTML></FONT></FONT>


CSharp/C# >> Why aren't arrays of constants equivalent to constant expressions?

by 100 » Fri, 09 Jan 2004 01:34:10 GMT


his is a multi-part message in MIME format.


Hi JJ,
I belive this is FxCop mistake. FxCop is right in one, though - declaring an array as readonly doesn't protect your array of changing its items. Consider this

I always can do

someobj.days[0] = "Fri";

what you protect against is that I cannot make
someobj.days = new string[]{"Wed", "Thu", "Fri"}

So *constant* is not fully covered by *readonly*

But this is the best you can do about the arrays at the moment, I believe. FxCop gives you wrong advice.

If you want more constantness you can inherit your own class from CollectionBase let say and make it readonly strongly-typed collection. Then make an object of this collection visible to the rest of the classes via readonly data member or get-only property.

HTH
B\rgds
100


"JJ Feminella" <external#jjnexus@com> wrote in message news: XXXX@XXXXX.COM ...
This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a constant declarator [involve] constant expressions'. A constant expression is defined as 'an expression that can be fully evaluated at compile-time ... Therefore, the only possible values for constants of reference types are string and null.'

In other words, constant arrays of any otherwise constant type are not legal C#. I understand that this is the case because string[] is really of type System.Array, which is an object (also a dead giveaway since we used the new operator). Fine. I'll get the next best thing and use static readonly in place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon", "Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant array? Any help would be greatly appreciated. Thanks.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1276" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>Hi JJ,</FONT></DIV>
<DIV><FONT face=Arial size=2>I belive this is FxCop mistake. FxCop is right in
one, though - declaring an array as readonly doesn't protect your array of
changing its items. Consider this</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I always can do </FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>someobj.days[0] = "Fri";</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>what you protect against is that I cannot
make</FONT></DIV>
<DIV><FONT face=Arial size=2>someobj.days = new string[]{"Wed", "Thu",
"Fri"}</FONT></DIV>
<DIV><FONT face=Arial s

CSharp/C# >> Why aren't arrays of constants equivalent to constant expressions?

by Rafael M. Munoz [MSFT] » Fri, 09 Jan 2004 03:19:12 GMT

for XXXX@XXXXX.COM

Sorry for the injection of this post but this I am trying to get a hold of
XXXX@XXXXX.COM to discuss the MVP program and was hoping they could email me at
XXXX@XXXXX.COM . Thanks

--
Rafael M. Munoz
Microsoft PSS Global Community
MVP Lead - .NET / VB / VC# / VJ#

This posting is provided 'AS IS' with no warranties, and confers no rights.
Microsoft Strategic Technology Protection Program for information -
http://www.microsoft.com/security.

---------------------


Hi JJ,
I belive this is FxCop mistake. FxCop is right in one, though - declaring an
array as readonly doesn't protect your array of changing its items. Consider
this

I always can do

someobj.days[0] = "Fri";

what you protect against is that I cannot make
someobj.days = new string[]{"Wed", "Thu", "Fri"}

So *constant* is not fully covered by *readonly*

But this is the best you can do about the arrays at the moment, I believe.
FxCop gives you wrong advice.

If you want more constantness you can inherit your own class from
CollectionBase let say and make it readonly strongly-typed collection. Then
make an object of this collection visible to the rest of the classes via
readonly data member or get-only property.

HTH
B\rgds
100




This statement is legal C#:

public const string day = "Sunday";

but this statement is not:

public const string[] days = new string[] { "Sun", "Mon", "Tue" };

The C# Programmer's Reference specifies that 'the only valid values of a
constant declarator [involve] constant expressions'. A constant expression
is defined as 'an expression that can be fully evaluated at compile-time ...
Therefore, the only possible values for constants of reference types are
string and null.'

In other words, constant arrays of any otherwise constant type are not legal
C#. I understand that this is the case because string[] is really of type
System.Array, which is an object (also a dead giveaway since we used the new
operator). Fine. I'll get the next best thing and use static readonly in
place of where I'd like to use const. The statement becomes:

public static readonly string[] days = new string[] { "Sun", "Mon",
"Tue" };

and the compiler's happy.

But now if I run FxCop on an assembly containing this statement, it gets mad
at me:

'... Fields that are arrays should not be readonly'
'Make the array 'const' to truly protect its contents.'

What the heck? Am I missing something here? How do you declare a constant
array? Any help would be greatly appreciated. Thanks.

Similar Threads

1. Elements of constant array as constant expressions.

2. C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression"

3. C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression"

C/C++ language proposal: 
  Change the 'case expression' from "integral constant-expression" to "integral expression"

The C++ Standard (ISO/IEC 14882, Second edition, 2003-10-15)
says under 6.4.2(2) [see also 5.19]:

      case constant-expression : 

I propose that the case expression of the switch statement
be changed from "integral constant-expression" to "integral expression".
This opens up many new possibilities since then also function calls
would be permitted in the case expression.
The old case case would continue to function since
it is a subset of the new case case.

Example usage:

//...
int f() 
  { 
    //...
    return BLA1;
  }

int g() 
  { 
    //...
    return BLA2;
  }

int h() 
  { 
    //...
    return BLA3;
  }

int y, x = f();
switch (x)
  {
    case 123 : y = g(); break;
    case g() : y = 456; break;  // using new case feature, ie. func-call  
    case h() : y = 789; break;  // ditto
    default  : y = -1;  break;
  }

4. Array size as constant expression

5. size of array is not an integral constant-expression

#include <vector>
using namespace std;

template <typename Iter>
int
foo(Iter first, Iter last, int nn)
{
 const size_t n = last - first;
 double buf[n];
 return 0;
}

int
main(int argc, char **argv)
{
 vector<double> x;
 foo(x.begin(), x.end(), argc);
 return 0;
}

foo.cc:17:   instantiated from here
foo.cc:9: error: size of array is not an integral constant-expression

g++ 4.2.1

Is this error specific to g++ 4.x?  g++ 3.6.4 and g++ 2.9.5 have no
problems with it, but that doesn't mean they are right.  Is there some
reason to expect this to fail.

There are a few interesting workarounds that point to this being
unexpected behavior... I'll post those next.

6. an array reference cannot appear in a constant-expression

7. declaration of array with non-constant expression?

Hi Everyone,

I've just come across an expression that I always thought should not
compile:

int j = 0;
int b[j];

But it compiles fine under gcc4.3.4. Obviously it is not very useful,
but what does it mean? No memory can be allocated at compile time, but
b seems to act like a pointer. I've browsed through the standard and
found nothing that would indicate that this is legal. The section on
declarations of arrays (8.3.4) says that only constant expressions are
allowed in brackets. Can anyone please explain this to me?

Thank you.

-Mike

8. Is array element be constant expression