auto keyword strange behavior in C++11 - c++

Theoretical question only - why i can't write such code:
auto auto foo = 0;
First auto keyword - storage class specifier (yeah, i know that it's useless and deprecated in C++11), second auto keyword - auto type-specifier.
So what's wrong?
And again - i don't really want to use this in real code.

The auto storage class specifier is not "useless and deprecated in C++11," it has been removed entirely. The auto keyword is no longer a storage class specifier and cannot be used as one.
In C++11, auto is a simple type specifier.

From the Stroustrup's FAQ:
....The old meaning of auto ("this is a local variable") is now
illegal. Several committee members trawled through millions of lines
of code finding only a handful of uses -- and most of those were in
test suites or appeared to be bugs.
Which indicates there's much not code used using "auto" as storage specifier.

Related

#define was changed to constexpr auto [duplicate]

This question already has answers here:
Is it bad practice to specify an array size using a variable instead of `#define` in C++? (C error: variably modified at file scope) [closed]
(3 answers)
Closed 3 years ago.
I defined some code in c++, ex:
#define array_width 3;
Visual Studio will suggest changing to:
constexpr auto array_width = 3;
what's the reason to change? and what is the benefit?
Thanks.
The main reason for these suggestions is that the preprocessor does nothing but simple textual replacement (no type checking or similar things a compiler performs). There are many potential pitfalls when using the preprocessor - when you can avoid it, do so. `constexpr´ is one of the building blocks that allow for fewer macros these days.
To back this with an authority: From S. Meyers, Effective C++, Item 2 ("Prefer consts, enums, and inlines to #defines"):
Things to Remember
For simple constants, prefer const objects or enums to #defines
[...]
From S. Meyers, Effective Modern C++, Item 15 ("Use constexpr whenever possible"):
Things to Remember
constexpr objects are const and are initialized with values known during
compilation.
[...]
constexpr objects and functions may be used in a wider range of contexts than non-constexpr objects and functions.
Macros work by substituting text. With macro the following example code will be ill-formed:
struct foo
{
int array_width{};
};
So in modern C++ one should prefer to avoid macros when there are alternatives available. Also it is a good idea to use UNIQUE_PREFIX_UPPER_CASE naming convention for macros to avoid possible clashes with normal code.

Initialising constexpr - " illegal initialization of 'constexpr' entity with a non-constant expression"

I have two enum class types: Type and SocketType. The following code won't compile and fails with the message mentioned in the question, in VC++ 2017:
static constexpr std::map<Type,SocketType> PacketTypeMap =
{
{Type::JUSTJOINED, SocketType::TCP},
{Type::CHAT_MESSAGE, SocketType::TCP},
{Type::REQUEST_WORLD, SocketType::TCP},
{Type::DATA_WORLD, SocketType::TCP},
{Type::DATA_PLAYER, SocketType::UDP},
{Type::RESPAWN_PLAYER, SocketType::TCP}
};
Been trying some variations and nothing works, but I'm sure I'm just missing something simple with the syntax.
std::map is not compatible with constexpr. There exists an experimental(?) library called frozen, which provides a constexpr-compatible frozen::map (besides frozen::unordered_map, frozen::string, and others).
However, most probably you just want to pick a simpler solution (e.g., a switch statement in a constexpr function).
Migrating the answer from the comments section into the answer section.
There are no constexpr maps. It uses dynamic allocation, which is not possible with constexpr. Get rid of constexpr, or use a different container for compile-type map.

Does auto do something complete different in C++ as in C?

After reading this post: Is there a downside to declaring variables with auto in C++?
I was asking myself: Is really no one of the answerers aware of auto not beeing a type but a storage-class specifier.
Or is auto since C++11 something different as the storage-class specifier in plain C?
If so, does this break the compability between C and C++?
(I'm aware that they official never were supporting each other in anyway, but my experience was that the C++ comittee tryed to stay as close to C as possible when evver it was acceptable. But now changing an obsolete, but abyway existing keyword instead of just adding a new one. Why here doing such a break of consistens?)
As of c++11 auto means to infer the type. It was used because adding a new keyword would have caused more c++ programs to break. As a storage specifier, auto is useless because it is the default if no specifier is added.
The only alternative was to follow the approach used in C generics of using a name starting with an underscore. This would have lead to an ugly keyword, that is meant to be regularly used.

Is `auto` specifier slower in compilation time?

Since C++11 we can use auto a = 1+2 instead of int a = 1+2 and the compiler deduces the type of a by itself. How does it work? Is it slower during compile time (more operations) than declaring the type myself?
auto is asking the C++11 compiler to make some limited kind of type inference (look into Ocaml if you want some more sexy type inference language). But the overhead is compile-time only.
If you replace auto a=1+2; with int a=1+2; (both have the same meaning, see answer by simplicis) and if you ask your compiler to optimize (and probably even without asking for optimizations) you'll probably get the same machine code. See also this.
If using GCC try to compile a small C++11 foo.cc file with g++ -Wall -fverbose-asm -O -S foo.cc and look (with an editor) into the generated foo.s assembler file. You'll see no difference in the generated code (but the assembler file might perhaps change slightly, e.g. because of metadata like debug information etc.)
If you are concerned about slower compile-time I guess that using auto is not a decisive factor (probably, overloading could be more costly in compilation time). C++11 is nearly designed to practically require a lot of optimizations (in particular sophisticated inlining and constant folding and dead code elimination), and its "parsing" (notably header inclusion and template expansion) is costly.
Precompiling headers and parallel builds with make -j (and perhaps ccache or distcc) might help in improving the overall compilation time, much more than avoiding auto.
And if you wanted to systematically avoid auto (in particular in range-for loops like std::map<std::string,int> dict; for (auto it: dict) {...}) you'll end up typing much more source code (whose parsing and checking takes significant time) with more risks of error. As explained here, you might guess slightly wrongly the type, and expliciting it (slightly wrongly) might slow down the execution of your code because of additional conversions.
If using GCC you might pass the -ftime-report to g++ and get time measurements about various GCC passes and phases.
The compiler knows the type an expression (like 1 + 2) evaluates to. That's just the way the language works -- both operands are of type int so the result is int as well. With auto a, you are just telling the compiler to "use the type of the initializing expression".
The compiler does not have to do any additional work or deducing here. The auto keyword is merely relieving you from figuring out the expression and writing the correct type. (Which you might get wrong, with probably unintended side-effects -- see this question (and the top answer) for an example how auto can avoid unintended run-time conversions and copying.
The auto keyword really comes into its own with iterators:
std::vector< std::string >::const_iterator it = foo.cbegin();
versus
auto it = foo.cbegin();
How does it work:
From the ISO/IEC:
...The auto specifier is a placeholder for a type to be deduced (7.1.6.4). The other simple-type-specifiers specify
either a previously-declared user-defined type or one of the fundamental types...
7.1.6.4 auto specifier
The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializer
or that a function declarator shall include a trailing-return-type.
The auto type-specifier may appear with a function declarator with a trailing-return-type in any
context where such a declarator is valid.
Otherwise, the type of the variable is deduced from its initializer. The name of the variable being declared
shall not appear in the initializer expression. This use of auto is allowed when declaring variables in a
block, in namespace scope, and in a for-init-statement; auto shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more initdeclarators, each of which shall have a non-empty initializer...
Example:
auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
static auto y = 0.0; // OK: y has type double
auto int r; // error: auto is not a storage-class-specifier
Is it faster:
The simple answer is Yes, by using it a lot of type conversions could be omitted, however, if not used properly it could become great source of errors.
In one of the interviews from Bjarne Stroustrup, he said that auto keyword has resulted in win-win situation for coders and compiler implementers.

Why old usage (c++03) of auto does not compile under C++11?

I know that auto has a little usage before because it is the default for variables (opposite to static) - see question
Consider however valid C++03 code where, maybe for self-explanatory, this keyword was used:
auto int foo2 = 8;
It compiles under C++03, and does not compile under C++11.
Is there any reason for not being back-compatible with C++03?
What was the source of standard committee opinion that this keyword was not used? Are there any statistics of keyword usage?
BTW i tested with gcc - maybe this is a compiler bug?
It was known that this breaks compatibility and is mentioned in Appendix C 2.3 Clause 7 of the standard. Given how useless auto has been and that it is really easy to fix the cost was deemed acceptable.
As for keyword statistics: Some companies with huge code-bases are on the committee, they probably know if it was acceptable, but I could not dig up any full statistics.
I did some standards archeology and the oldest paper that talks about auto seems to be N1478, which refers to a reflector message for the first discussing of auto (all later papers don't talk about breaking compatibility or reasoning).
This was removed from C++11 because they have a new use for auto, and it would be confusing to allow auto auto foo2 = 8; to work. Nothing of significance is lost by removing this ancient and pointless declaration.