It seems that auto
was a fairly significant feature to be added in C++11 that seems to follow a lot of the newer languages. As with a language like Python, I have not seen any explicit variable declaration (I am not sure if it is possible using Python standards).
Is there a drawback to using auto
to declare variables instead of explicitly declaring them?
Other answers are mentioning drawbacks like "you don't really know what the type of a variable is." I'd say that this is largely related to sloppy naming convention in code. If your interfaces are clearly-named, you shouldn't need to care what the exact type is. Sure,
auto result = callSomeFunction(a, b);
doesn't tell you much. Butauto valid = isValid(xmlFile, schema);
tells you enough to usevalid
without having to care what its exact type is. After all, with justif (callSomeFunction(a, b))
, you wouldn't know the type either. The same with any other subexpression temporary objects. So I don't consider this a real drawback ofauto
.I'd say its primary drawback is that sometimes, the exact return type is not what you want to work with. In effect, sometimes the actual return type differs from the "logical" return type as an implementation/optimisation detail. Expression templates are a prime example. Let's say we have this:
Logically, we would expect
SomeType
to beVector
, and we definitely want to treat it as such in our code. However, it is possible that for optimisation purposes, the algebra library we're using implements expression templates, and the actual return type is this:Now, the problem is that
MultExpression<Matrix, Vector>
will in all likelihood store aconst Matrix&
andconst Vector&
internally; it expects that it will convert to aVector
before the end of its full-expression. If we have this code, all is well:However, if we had used
auto
here, we could get in trouble:Like this developer, I hate
auto
. Or rather, I hate how people misuseauto
.I'm of the (strong) opinion that
auto
is for helping you write generic code, not for reducing typing.C++ is a language whose goal is to let you write robust code, not to minimize development time.
This is fairly obvious from many features of C++, but unfortunately a few of the newer ones like
auto
that reduce typing mislead people into thinking they should start being lazy with typing.In pre-
auto
days, people usedtypedef
s, which was great becausetypedef
allowed the designer of the library to help you figure out what the return type should be, so that their library works as expected. When you useauto
, you take away that control from the class's designer and instead ask the compiler to figure out what the type should be, which removes one of the most powerful C++ tools from the toolbox and risks breaking their code.Generally, if you use
auto
, it should be because your code works for any reasonable type, not because you're just too lazy to write down the type that it should work with. If you useauto
as a tool to help laziness, then what happens is that you eventually start introducing subtle bugs in your program, usually caused by implicit conversions that did not happen because you usedauto
.Unfortunately, these bugs are difficult to illustrate in a short example here because their brevity makes them less convincing than the actual examples that come up in a user project -- however, they occur easily in template-heavy code that expect certain implicit conversions to take place.
If you want an example, there is one here. A little note, though: before being tempted to jump and criticize the code: keep in mind that many well-known and mature libraries have been developed around such implicit conversions, and they are there because they solve problems that can be difficult if not impossible to solve otherwise. Try to figure out a better solution before criticizing them.
As I described in this answer
auto
can sometimes result in funky situations you didn't intend. You have to explictly sayauto&
to have a reference type while doing justauto
can create a pointer type. This can result in confusion by omitting the specifier all together, resulting in a copy of the reference instead of an actual reference.I think
auto
is good when used in a localized context, where the reader easily & obviously can deduct its type, or well documented with a comment of its type or a name that infer the actual type. Those who don't understand how it works might take it in the wrong ways, like using it instead oftemplate
or similar. Here are some good and bad use cases in my opinion.Good Uses
Iterators
Function Pointers
Bad Uses
Data Flow
Function Signature
Trivial Cases
What no one mentioned here so far, but for itself is worth an answer if you asked me.
Since (even if everyone should be aware that
C != C++
) code written in C can easily be designed to provide a base for C++ code and therefore be designed without too much effort to be C++ compatible, this could be a requirement for design.I know about some rules where some well defined constructs from
C
are invalid forC++
and vice versa. But this would simply result in broken executables and the known UB-clause applies which most times is noticed by strange loopings resulting in crashes or whatever (or even may stay undetected, but that doesn't matter here).But
auto
is the first time1 this changes!Imagine you used
auto
as storage-class specifier before and transfer the code. It would not even necessarily (depending on the way it was used) "break"; it actually could silently change the behaviour of the program.That's something one should keep in mind.
1At least the first time I'm aware of.
Another irritating example:
generates a warning (
comparison between signed and unsigned integer expressions [-Wsign-compare]
), becausei
is a signed int. To avoid this you need to write e.g.or perhaps better: