Why would this compile?

I created a "const" for a value previously explicitly stated several times in my code:

private static readonly int QUARTER_HOUR_COUNT = 96;

When I did a search-and-replace of 96 for QUARTER_HOUR_COUNT, I inadvertently also replaced the declaration, so it became:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;

...yet it compiled. I would think that it would disallow that. Why was it accepted by the compiler as a valid declaration?

Upvotes: 28

Views: 1613

Answers (5)

Anirudha
Anirudha

Reputation: 32787

The IL code generated by the code is this:

 IL_0007:  ldsfld     int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack
 IL_000c:  stsfld     int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field

Since the default value of QUARTER_HOUR_COUNT is 0,the 0 is assigned to QUARTER_HOUR_COUNT

Upvotes: 6

RobV
RobV

Reputation: 28646

As others have implied value types like int have a default value so declaring a variable without explicitly initializing it means it still has a value.

You can find out the default value for any type like so:

int i = default(int);

Or more generally:

T t = default(T);

Note that for reference types the default will be null, only value types will have default values.

Upvotes: 0

Phillip Schmidt
Phillip Schmidt

Reputation: 8818

Because the compiler will break this line down:

private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;

Basically into the IL equivalent of:

private static readonly int QUARTER_HOUR_COUNT;
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;

And then obviously that'll get broken down more too, but the above should suffice to illustrate my point.

So technically it'll exist with a default value of zero at the time it gets used.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1499950

I would think that it would disallow that. Why was it accepted by the compiler as a valid declaration?

Presumably because the language specification allows it. Do you have a specific rule in the language specification which you think prohibits it?

If your question is really "why doesn't the language specification prohibit this" - I suspect it's because it's probably quite hard to make sure you only prohibit things you really want to prohibit, while actually prohibit all such things.

You could argue that for simple cases of assignment directly back to itself, it would be good to have a special case in the language spec, but it would introduce complexity into the language for relatively little benefit.

Note that even if you didn't get an error, I'd expect you to get a warning - something like this:

Test.cs(3,33): warning CS1717: Assignment made to same variable; did you mean to assign something else?

Also note that if you make it a const instead of just a static readonly variable, then you do get a compile-time error:

Test.cs(3,23): error CS0110: The evaluation of the constant value for 'Program.QUARTER_HOUR_COUNT' involves a circular definition

Also note that by .NET naming conventions, this ought to be called QuarterHourCount, rather than having a SHOUTY_NAME.

Upvotes: 23

tsells
tsells

Reputation: 2771

Because the variable was initialized as 0 and then set to itself.

My guess would be that it would be doing a new Int() prior to setting to itself which would initialize it to zero.

Upvotes: 5

Related Questions