On using 'auto' and 'var'

Programmers love to argue about coding standards, and one of the most contentious points is whether or not it should be allowed to use the equivalen to the “auto” keyword in C++ (in C# it’s called “var”, other language shave similar things). This is a keyword that does simple type propagation and lets you name a value without explicitly giving its type.

I don’t actually care all that much about coding standards, but this one bugs me because it seems to me that the main argument against allowing “auto” is a very transparent post-hoc justifications for “It’s unfamiliar to me, therefore bad”.

The basic argument against using “auto” that is that it makes the code harder to read because you can’t tell what type of a variable is just from looking at it.

Let’s assume we have a class defined in a header like so:

// MyClass.h
class MyClass {
    std::string name;
    void DoStuff();
}

// MyClass.cpp
void MyClass::DoStuff(){
    /* ... */
    AddName(name);
    /* ... */
}

So basically in the DoStuff method we access the member variable called name and pass it to some function. I don’t think anyone would really have any major objections to this code, despite the fact that the type of name isn’t really easily inferred from within the DoStuff method.

Now, let’s say you had code like this instead:

void SomeOtherFunction(){
    /* ... */
    auto otherName = GetOtherName();
    AddName(otherName);
    /* ... */
}

And holy hell people will lose their goddamn minds over this. It’s apparently some kind if atrocity because we don’t spell out the type of the otherName variable. So while it’s fine to to just use a value without explicitly spelling out the type in the former case, apparently in this case it’s completely unacceptable. If this code is so unreadable, then why the hell doesn’t MyClass::DoStuff suffer from the same problem? I have never heard anyone argue that all class members should be assigned to a local, fully-specified, variable before using them in order to “make the code more readable”.

It makes no sense to me. However, it’s easily fixed - just replace the code with this:

void SomeOtherFunction(){
    /* ... */
    AddName(GetOtherName());
    /* ... */
}

And just like that everyone is on board with the code again.

It’s hard to come to any other conclusion that the objection to “auto” is based on lack of familiary rather than any kind of rational reasoning. The fact is that we use values without specifying the type all the time. In this last example we don’t even give the intermeadite value a name for heavens sake, and yet I’ve never met anyone who argues that this makes the code inscrutable. If you’re okay with this code, it doesn’t make any sense to argue that the “auto”-based version is too cryptic because it omits the type.

If you don’t care about either the name or a type for some value, you can just use the value anonymously (like the last example). If you do care about the name and the type you can introduce a named variable with the type specified. Programmers already made this tradeoff just fine before the “auto” keyword was even introduced. We now just have one more point on that spectrum - where you can give something a name without having to write out the type.

In my opinion it doesn’t make a whole lot of sense that the two extreme options are both considered perfectly readable, but have the in-between alternative isn’t.

comments powered by Disqus