24
Var/Auto is Ugly and in Some Cases, Downright Evil.
2 Comments | Posted by softwarepurist in C#, C++, STL
In this post, I’m going to describe a set of keywords, which effectively serve the same purpose. In C#, there is the var keyword. In C++, there is the auto keyword. Effectively, what they let you do is to automatically inter the type of a variable from the context on the right hand side. Here’s an example, in C#:
var myVar = new MyClass();
and an example in C++:
auto myVar = MyClass();
The problem I have is, while this allows you a tremendous amount of flexibility, in saving redundant typing, it also potentially nullifies some of the benefits of using a language which supports type safety, because you can do some pretty nasty things which destroy the readability and can potentially introduce some subtle bugs. Worse still, tools like Resharper encourage, potentially poor usages of var. Here’s another example of the var problem:
var myVar = new MyClass().DoThis().DoThat().DoSomethingElse().NowGet();
Ok, what’s the type? Don’t know? Me neither. I find this problematic. As such, as I’d like to establish some guidelines for better usage of var/auto, taking some common use cases. I’ll probably switch back and forth with examples from C++ and C#, just to illustrate the point. Here we go:
1) Usage case 1:
var x = new Y();
I consider this usage a minor evil, even though some like it a lot. Here’s my major problem: You have type inference on the wrong side. The point of using a language which supports type safety, is, well, you support the type system and let it help you. If you don’t want that, may I suggest a language that is dynamically typed? It would be nice, if var, instead worked this way:
Y x = new infer-this-type();
As a general rule, we would prefer to infer the type that’s on the right hand side, not the left. This feature is not available in a lot of languages, so for now, I would simply suggest not using var. Go with the old:
Y x = new Y();
2) Usage case 2:
var x = GetY();
Again, with this one, I prefer not to use var, for the same reason as before, with an added caveat. First, of all, you should avoid using var to avoid typing a simple type. Secondly, you can’t even figure out what the type is from reading the code. Not good. On a scale of 1 to evil, I consider this a significant evil.
3) Usage case 3:
for (typename std::vector
{
...
}
Becomes:
for (auto iter = container.begin(); iter != container.end(); ++iter)
{
...
}
In this case, I can justify using var/auto, so I consider using auto a minor evil. However, C++ has a better mechanism for doing this. It’s called typedef. For example:
typedef typename std::vector
for (MyIter iter = container.begin(); iter != container.end(); ++iter)
{
...
}
So, in C++, I have trouble finding ANY usage, where I really like auto. However, in C#, there is no typedef, so I’m fine with usage of var, in the case of complicated nested classes.
Conclusion
Concluding, as you figured, I don’t like the usage of var or auto much. In a lot of cases, it is a minor evil. However, there are some major concerns: Readability and subverting some of the redundant checking that the type system supports. In C#, it is sometimes useful to save a lot of typing, due to the lack of the typedef keyword, while in C++, it is rarely useful. In a future article, I will tackle C#’s dynamic keyword, which I dislike far more than var. Stay tuned.
2 Comments for Var/Auto is Ugly and in Some Cases, Downright Evil.
RM | April 21, 2011 at 10:59 am
Leave a comment!
<< Dynamic: The New C# Keyword That Has Abuse Written All Over It


I don’t really see the difference between use cases 2 and 3 here. In use case 3 you say that “In this case, I can justify using var/auto, so I consider using auto a minor evil” but fail to explain why – is it because you are familiar with the return type of the function you’re calling so would rather not type it out?
The point of auto, as i can see it, is that you are aware of the code’s context – most people writing code can right click a function call and go and look at the signature if they’re not sure of the type. Staring at a piece of code like “var myVar = new MyClass().DoThis().DoThat().DoSomethingElse().NowGet();” out of context is not a real situation faced by a programmer.
Also, I can’t help but point out that inferring the type on the right hand side of the assignment wouldn’t make any sense for a language where classes are reference types, because the compiler would have to guess which constructor out of every subtype of Y you want to call.