Reputation: 10237
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
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
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
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
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
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