Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

What were the design decisions that argued in favour of void not being constructable and not being allowed as a generic type? After all it is just a special empty struct and would have avoided the total PITA of having distinct Func and Action delegates.

(C++ allows explicit void returns and allows void as a template parameter)

share|improve this question
10  
@Oded Considering that Eric Lippert has an account and participates on Programmers, I think he just did. –  Thomas Owens Jan 20 '12 at 13:48
2  
@BenVoigt It doesn't necessarily require a single individual's knowledge, although there is a single person here who can (easily, I'd assume) give the single right answer. Anyone familiar with the specification can probably answer the question, especially if they have a knowledge of programming language design. It's also an interesting language design/language implementation question, which is on-topic here. –  Thomas Owens Jan 20 '12 at 15:35
3  
@BenVoigt: Why are you so keen to have a perfectly valid and interesting question closed for no good reason, other to satisfy your own pedantry? I had a search and couldn't find the answer; maybe someone here has read a blog post about it, maybe the people who took the decision want to answer the question, maybe someone got chatting to the people who made the decision about this and asked the question themselves and can pass on the answer. I've stopped posting on this site and SO pretty much because people seem much more interested in getting a question closed than in answering questions. –  user23157 Jan 20 '12 at 15:52
1  
I could point out the the "big point" questions and answers here and especially on SO are generally of the form "what does this syntax mean?" Those questions hardly ever get closed because everyone can pile in and reel out the definitions for const poiners to const objects. The more interesting questions that lie off the beaten track get hounded off the site for some pedantic reason: seriously it's only a few kilobytes in a data warehouse somewhere. Can we all just relax and embrace learning rather than imposing arbitrarily interpreted rules that serve very little purpose? –  user23157 Jan 20 '12 at 15:58
2  
@ThomasOwens: I am in a sense more active on this site than on SO. On this site I post an answer to about one question in every 300. On SO I post an answer to about one question in every 1500. The difference in sheer-number-of-answers activity is attributable to the much higher number of opportunities for answering C# questions on SO. –  Eric Lippert Jan 20 '12 at 20:05
show 13 more comments

2 Answers

up vote 35 down vote accepted

The fundamental problem with "void" is that it does not mean the same thing as any other return type. "void" means "if this method returns then it returns no value at all." Not null; null is a value. It returns no value whatsoever.

This really messes up the type system. A type system is essentially a system for making logical deductions about what operations are valid on particular values; a void returning method doesn't return a value, so the question "what operations are valid on this thing?" don't make any sense at all. There's no "thing" for there to be an operation on, valid or invalid.

Moreover, this messes up the runtime something fierce. The .NET runtime is an implementation of the Virtual Execution System, which is specified as a stack machine. That is, a virtual machine where the operations are all characterized in terms of their effect on an evaluation stack. (Of course in practice the machine will be implemented on a machine with both stack and registers, but the virtual execution system assumes just a stack.) The effect of a call to a void method is fundamentally different than the effect of a call to a non-void method; a non-void method always puts something on the stack, which might need to be popped off. A void method never puts something on the stack. And therefore the compiler cannot treat void and non-void methods the same in the case where the method's returned value is ignored; if the method is void then there is no return value so there must be no pop.

For all these reasons, "void" is not a type that can be instantiated; it has no values, that's its whole point. It's not convertible to object, and a void returning method can never, ever be treated polymorphically with a non-void-returning method because doing so corrupts the stack!

Thus, void cannot be used as a type argument, which is a shame, as you note. It would be very convenient.

With the benefit of hindsight, it would have been better for all concerned if instead of nothing whatsoever, a void-returning method automatically returned "Unit", a magical singleton reference type. You would then know that every method call puts something on the stack, you would know that every method call returns something that could be assigned to a variable of object type, and of course Unit could be used as a type argument, so there would be no need to have separate Action and Func delegate types. Sadly, that's not the world we're in.

For some more thoughts in this vein see:

share|improve this answer
    
Cheers Eric, many thanks. –  user23157 Jan 20 '12 at 20:32
    
C++ supports it without having to use a magical singleton type. But I assume that has to do with C++ using a completely different "generics" style then C#. –  Winston Ewert Jan 20 '12 at 20:37
2  
@WinstonEwert - I'm pretty sure C++ doesn't support generics at all, but rather has templates, which are fundamentally different. As I understand it, with templates the compiler is doing a global search and replace with your type parameters, but with generics, the type system is creating a proper type. I also think that's why C++ template errors were so obtuse. I'm sure Eric will correct me if I said anything not quite right –  Adam Rackis Jan 20 '12 at 20:56
    
@AdamRackis, that's why I had generics in quotation marks. –  Winston Ewert Jan 20 '12 at 20:59
    
@AdamRackis: Couldn't have said it better myself. Templates are in some sense not a type system feature in C++. (In another sense they define a whole new type system of their own, but let's not go there.) –  Eric Lippert Jan 20 '12 at 21:00
show 7 more comments

From: http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in-runtime

This is actually by design - we don't allow any instance of the void type (along with many other types in the runtime). You can't CreateInstance a void or void[] either. We plugged these type holes for security.

I can't for the life of me see how void is a security hole, but... such it says.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.