ordering const declarations

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I found a bug??? with constants in csharp. Consider the following:

internal static readonly int MAX_BUFFER_SIZE=8192;
internal static readonly int
MAX_MESSAGE_LENGTH=MAX_BUFFER_SIZE-USER_DATA_OFFSET;

internal static readonly int USER_DATA_OFFSET=29;


When the constant MAX_MESSAGE_LENGTH is calculated the USER_DATA_OFFSET
is 0 at this stage and the result is 8192 rather than 8192-29 as
expected.

Now I know the order of static variables is undetermined across
different class files. But (and I really can't remember cos I haven't
done C/C++ for years) I thought this was calculated corrected in C/C++.
If this is not the case then csharp should flag the 2nd line as an
error if it doesn't know what USER_DATA_OFFSET is. Better than leaving
it as 0 and letting it compile without problems. Now I need to verify
that all constants are used after they are declared.
 
I found a bug??? with constants in csharp.

The behaviour you describe is as specified.
Consider the following:

internal static readonly int MAX_BUFFER_SIZE=8192;

Note that 'static readonly' fields aren't actually constants, but static
readonly fields. You can use 'const' if you really need a constant (but
it's only useful for values that can be calculated at compile time). The
C# compiler will correctly reorder the initializations of constants as
long as there isn't a circular reference in the initializers (section
17.3 of ECMA-334 4th ed).
internal static readonly int
MAX_MESSAGE_LENGTH=MAX_BUFFER_SIZE-USER_DATA_OFFSET;

internal static readonly int USER_DATA_OFFSET=29;

The fields of a class which have initializer expressions, whether static
or not, are initialized in the order they occur in the source. You can
check section 17.4.5 of ECMA-334 4th ed:

"The default value initialization described in §17.4.3 occurs for all
fields, including fields that have variable initializers. Thus, when a
class is initialized, all static fields in that class are first
initialized to their default values, and then the static field
initializers are executed in textual order. Likewise, when an instance
of a class is created, all instance fields in that instance are first
initialized to their default values, and then the instance field
initializers are executed in textual order. When there are field
declarations in multiple partial type declarations for the same type,
the order of the parts is unspecified. However, within each part the
field initializers are executed in order."
But (and I really can't remember cos I haven't
done C/C++ for years) I thought this was calculated corrected in C/C++.

C++ doesn't really distinguish between constants and readonly static
fields. The distinction is only important for versioning of dynamically
linked object libraries.

-- Barry
 
I found a bug??? with constants in csharp. Consider the following:

internal static readonly int MAX_BUFFER_SIZE=8192;
internal static readonly int
MAX_MESSAGE_LENGTH=MAX_BUFFER_SIZE-USER_DATA_OFFSET;

internal static readonly int USER_DATA_OFFSET=29;

When the constant MAX_MESSAGE_LENGTH is calculated the USER_DATA_OFFSET
is 0 at this stage and the result is 8192 rather than 8192-29 as
expected.

That's a fault in your expectations, not in the compiler.
Now I know the order of static variables is undetermined across
different class files. But (and I really can't remember cos I haven't
done C/C++ for years) I thought this was calculated corrected in C/C++.

The behaviour in C/C++ doesn't affect the behaviour in C#.
If this is not the case then csharp should flag the 2nd line as an
error if it doesn't know what USER_DATA_OFFSET is. Better than leaving
it as 0 and letting it compile without problems. Now I need to verify
that all constants are used after they are declared.

If that's hard, then I'd suggest you've got too many constants. Note
that even if you couldn't directly refer to the variable in the
initializer, it would be very hard for the language to spot the mistake
if you wrote something along the lines of:

internal static readonly int MAX_MESSAGE_LENGTH= PerformSomeCalc();

where PerformSomeCalc returned MAX_BUFFER_SIZE-USER_DATA_OFFSET.
 

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

Back
Top