12

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?

6
  • optional parameters were added after the fact. Commented Sep 11, 2013 at 12:07
  • Look at the compiler message. Is probably tells you something. Commented Sep 11, 2013 at 12:09
  • @DanielA.White - so was default, IIRC. It was only added when generics were. Commented Sep 11, 2013 at 12:11
  • @usr Well, the compiler message is the source of the confusion mate. Commented Sep 11, 2013 at 12:11
  • It would appear that it is part of the spec. I really should read that more thoroughly at some point!! Commented Sep 11, 2013 at 12:15

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

2 Comments

You should also say that default is an operator evaluated at runtime, then this answer is perfect
@Marcin 7.19 of 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
4

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.

10 Comments

Agreed, but the definition of default(DateTime) being "compile-time constant" in one situation and not in another is in question, not its use ;-)
PI can only have the value 3.14... but I still think it's usefull.
@AdamHouldsworth The error I get is The type 'System.DateTime' cannot be declared const
@xanatos Ah, there are two errors there then, build reports both but the IDE only reports one.
@AdamHouldsworth A more interesting example that you can add is that you can't use default(DateTime) as an attribute parameter :-)
|
4

default() is evaluated at runtime. DateTime.MinValue is not declared as const.

Only symbols declared as const can be used in member initialisation and attribute declarations.

Optional paramters are a special case. The compiler generates overloads for you. Semantically it wants a const, but technically, default is ok as the compiler knows how to use this in the generated overload.

MSDN states that optional parameters accept default() and new() by design http://msdn.microsoft.com/en-us/library/dd264739.aspx

Concerning the const definition;

A constant expression is an expression that can be fully evaluated at compile time.

I agree that the distinction is slight and it has tripped me up more than once.

2 Comments

I don't think that covers the question. I know DateTime.MinValue is not constant, but in one situation default(DateTime) is and in another situation it "isn't".
7.19 of 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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.