问题
Very short question but I couldn't find a solution on the web right now.
int test = 1 + 2;
Will 1 + 2
be performed during run- or compile-time?
Reason for asking:
I think most people sometimes use a literal without specifying why it has been used or what it means because they do not want to waste a bit performance by running the calculation and I believe the calculate happens during compiletime and has no effect on performance:
int nbr = 31536000; //What the heck is that?
instead of
int nbr = 365 * 24 * 60 * 60; //I guess you know what nbr is supposed to be now...
回答1:
Since your examples are essentially constant expressions (i.e. they consist of only constants or constructs that evaluate as such), they will be evaluated at compile time.
A constant-expression is an expression that can be fully evaluated at compile-time.
The type of a constantexpression can be one of the following: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, any enumeration type, or the null type.
The following constructs are permitted in constant expressions:
- Literals (including the null literal).
- References to const members of class and struct types.
- References to members of enumeration types.
- Parenthesized sub-expressions, which are themselves constant expressions.
- Cast expressions, provided the target type is one of the types listed above.
- The predefined
+
,–
,!
, and~
unary operators. - The predefined
+
,–
,*
,/
,%
,<<
,>>
,&
,|
,^
,&&
,||
,==
,!=
,<
,>
,<=
, and>=
binary operators, provided each operand is of a type listed above. - The
?:
conditional operator.
回答2:
The expression 1 + 2
in int test = 1 + 2
is considered to be a "constant-expression" according to the C# spec:
7.19 Constant expressions
A constant-expression is an expression that can be fully evaluated at compile-time.
In other words: when an expression can be fully evaluated at compile-time, it is considered to be a "constant expression", and those will be evaluated at compile-time.
Kind of a catch-22 when you want to discover the meaning of a constant expression and compile-time evaluation.
To apply the relevant parts of the spec to your example:
A constant expression must be [...] a value with one of the following types: [...] int [...].
Only the following constructs are permitted in constant expressions:
Literals (including the null literal).
[...]
The predefined +, –, *, /, %, <<, >>, &, |, ^, &&, ||, ==, !=, <, >, <=, and >= binary operators, provided each operand is of a type listed above.
[...]
Whenever an expression fulfills the requirements listed above, the expression is evaluated at compile-time.
The last line would be clearer if it would read:
Whenever an expression fulfills the requirements listed above, the expression is [considered to be a constant expression and will be] evaluated at compile-time.
When an expression contradicts any of the listed rules (including things such as using a non-const member invocation or a method call), it will not be considered a constant expression and thus be evaluated at runtime.
回答3:
Well just tested it with IlSpy
and for code :
private static void Main(string[] args)
{
int value = 365 * 24 * 60 * 60;
Console.WriteLine(value);
}
Compiled MSIL code is :
.....
IL_0000: nop
IL_0001: ldc.i4 31536000 // its calculated already
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call void [mscorlib]System.Console::WriteLine(int32)
IL_000d: nop
IL_000e: ret
} // end of method Program::Main
So it does calculate static expression in compile time to improve performance however if we change our code to :
double nbr = Math.Sqrt(365 * 24 * 60 * 60);
Console.WriteLine(nbr);
This time the final result will be populated on run-time because compiler doesn't know value that will be returned by Math.Sqrt()
on compile time.
MsIL code :
IL_0000: nop
IL_0001: ldc.r8 31536000
IL_000a: call float64 [mscorlib]System.Math::Sqrt(float64)
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: call void [mscorlib]System.Console::WriteLine(float64)
IL_0016: nop
IL_0017: ret
} // end of method Program::Main
来源:https://stackoverflow.com/questions/36451656/are-arithmetic-operations-on-literals-in-c-sharp-evaluated-at-compile-time