Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile-time constant discrepency

Tags:

c#

Update: This appears to be a compiler red-herring, as the following is actually valid:

const int MyInt = default(int);

The issue lies with DateTime not being a valid const, not the use of default.

The main source of the confusion for me was not realising that default(DateTime) is handled specifically in optional parameters (and I had arrived at a false conclusion that default(DateTime) was being treated as compile-time constant due to the error message omitting the other possible conditions). This is addressed by MarcinJuraszek in his answer.


Original Question:

This is shamelessly ripped from a comment from Marc Gravell from this answer to another question.

Why is the following valid:

// No compiler errors, default(DateTime) seems to satisfy the compile-time constant requirement.
public static void DoSomething(DateTime date = default(DateTime))
{ 
}

But the following not:

// Compiler error: "Constant initializer must be compile-time constant.
const DateTime MyDate = default(DateTime); 

As both appear to want "compile-time constants" (evident if you attempt to provide something like DateTime.MinValue to the optional parameter, the compiler complains that it isn't compile-time constant):

// Compiler error: Default parameter value for 'date' must be a compile-time constant.
public static void DoSomething(DateTime date = DateTime.MinValue) {}

What is going on behind the scenes that causes the compiler to treat these differently?

like image 203
Adam Houldsworth Avatar asked Sep 11 '13 12:09

Adam Houldsworth


People also ask

What does compile time constant mean?

A compile-time constant is a value that is computed at the compilation-time. Whereas, A runtime constant is a value that is computed only at the time when the program is running. 2. A compile-time constant will have the same value each time when the source code is run.

What is compile time constant and runtime constant?

A compile-time constant is computed at the time the code is compiled, while a run-time constant can only be computed while the application is running. A compile-time constant will have the same value each time an application runs, while a run-time constant may change each time.

Can we change the value of constant variable at compile time?

The constant variable values cannot be changed after its initialization. In this section we will see how to change the value of some constant variables. If we want to change the value of constant variable, it will generate compile time error.

What determines compile time?

Compile time is the period when the programming code (such as C#, Java, C, Python) is converted to the machine code (i.e. binary code). Runtime is the period of time when a program is running and generally occurs after compile time.


2 Answers

That's described in C# specification (10.6.1):

A fixed-parameter with a default-argument is known as an optional parameter, whereas a fixed-parameter without a default-argument is a required parameter. A required parameter may not appear after an optional parameter in a formal-parameter-list.

A ref or outparameter cannot have a default-argument. The expression in a default-argument must be one of the following:

  • a constant-expression
  • an expression of the form new S() where S is a value type
  • an expression of the form default(S) where S is a value type

But you're right, the error message asking for compile-time constant is not good.

like image 78
MarcinJuraszek Avatar answered Oct 03 '22 05:10

MarcinJuraszek


Because a const that can only have the value default(TypeOfCost) would probably be quite useless :-)... And you can't even change it later :-)

Note that default(TypeOfConst) is a constant-expression

From the C# specifications (5.0): 7.19 Constant expressions... A constant-expression is an expression that can be fully evaluated at compile-time.... Only the following constructs are permitted in constant expressions:... • **Default value expressions**

The error is that const DateTime is illegal..

10.4 Constants... The type specified in a constant declaration must be sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type.

like image 43
xanatos Avatar answered Oct 03 '22 03:10

xanatos