Understanding the C++ compiler [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Most vexing parse: why doesn't A a(()); work?
I am having this simple C++ issue that is making me wanna restart my CS degree all over again trying to learn something this time. ;)
Why this code doesn't compile:
vector<int> v(int());
v.push_back(1);
while this other one compiles without a single warning
vector<int> v((int()));
v.push_back(1);
It's even hard to find a difference at all (extra parenthesis were added :P).

It's called the most vexing parse.
vector<int> v(int());
Declares a function v that takes a function (taking no parameters returning an int) and returns a vector<int>. This is automatically "adjusted" to a function v that takes a pointer to a function (taking no parameters returning an int) and returns a vector<int>.
The extra pair of parentheses inhibits this interpretation as you can't place extra parentheses around parameter declarators in function declarations so (int()) can only be interpreted as an initializer for an object named v.
C++ has an explicit disambiguation rule that prefers to parse things (in this case int()) as declarators rather than expressions if it makes syntactic (but not necessarily semantic) sense.

Indeed its a function declaration. See: http://www.gotw.ca/gotw/075.htm

Related

is 'auto' in c++ similar to 'Object' in java? [duplicate]

This question already has answers here:
C++ auto keyword. Why is it magic?
(8 answers)
Closed 12 months ago.
In Java, Object takes the place of various class objects, but casting is needed. In the piece of code below, auto seems to be doing the same only that it does not need to be casted with a type variable.
It seems like a lazy (efficient?) way to progress through code. I might get accustomed to using auto instead of a specific type (in the example below, it would be 'int index'). There might be an occasion(s) where such incorporation would not be recommended.
piece of code:
vector<int> fCount(1001,0);
for(auto index : list)
{
++fCount[index];
}
Actually NO. Object in Java differs from auto in C++. In C++, auto keyword only can be applied to any type that can be deduced in compile-time, not run-time. In the code snippet you given, although the index is deduced to be an int, but if you try to use to use index in wherever context that the int cannot be used, compiler will complain.
auto is just a syntactic sugar that modern C++ offers, that you do not have to specify the type when compiler can deduce from the expression. Although you do not have to specify the type explicitly, compiler specifies it in implicit way. After the compiler deduced the type, you cannot use the variable as other type(if it cannot be implictly converted)

How is `auto a(b);` parsed in C++? [duplicate]

This question already has answers here:
C++ auto keyword. Why is it magic?
(8 answers)
Closed 3 years ago.
I came across a curious line of code of the form:
// Given the following definitions:
class B;
B b;
// Line of interest:
auto a(b);
I thought it must be a typo, but after some experimentation found out that it works, and seems to always call the copy constructor of the type of b (even if you have other classes that can also have a matching constructor, and even if you additionally delete the copy constructor for the type of b).
I don't know the technical name of such a statement, so I'm not sure how to search for it in cppreference or StackOverflow. How does the compiler parse this type of statement in general, and where is it documented?
--
Re: duplicate marking. I don't see how they've addressed this construct. I already know auto uses template type deduction, that doesn't clarify anything in this case.
How is auto a(b); parsed in C++?
Depends on what b is. If b is a type, then this is a declaration of function with name a with deduced return type and a single argument of type b.
If b is not a type, then this defines a variable by the name a whose type is deduced from the initialiser.
where is it documented?
The authoritative documentation is the standard document. The standard sections [dcl.type.auto], [dcl.ambig.res], [dcl.fct], [dcl.init] should be relevant.
There are also websites that offer the documentation in (arguably) more approachable manner.
This should also be covered by recent (as in, anything since 2011) introductory C++ books.
and even if you additionally delete the copy constructor for the type of b
I doubt this. Create a mcve.

How do I typedef a function type that returns a function of the same type in C++? [duplicate]

This question already has answers here:
Function Returning Itself
(10 answers)
Closed 3 years ago.
I would like to know how to declare a function type that returns a function of the same type using typedef in C++.
While watching a Golang talk given by Rob Pike on lexical scanning, I came across the following code snippet,
type stateFn func(*Scanner) stateFn
This is the exact behavior that I would like to replicate in C++.
I have tried using the following type definition,
typedef state_fn state_fn(Scanner &);
But this gives me the error function returning function is not allowed.
Is it possible at all to do something like this? If not, how do I do something similar?
You cannot return functions in C++. See [dcl.fct]p10:
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
However, you can return some form of callable (that may be wrapping a function of the same type).

Why does using parentheses with a default constructor result in creation of the variable? [duplicate]

This question already has answers here:
What is the purpose of a declaration like int (x); or int (x) = 10;
(2 answers)
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
After watching Louis Brandy talk at CppCon 2017 I was shocked to discover that this code actually compiles:
#include <string>
int main() {
std::string(foo);
return 0;
}
And for some reason std::string(foo) it is identical to std::string foo i.e. declaring a variable. I find it absolutely counterintuitive and can't see any reason for C++ to work that way. I would expect this to give an error about undefined identifier foo.
It actually makes expressions like token1(token2) have even more possible interpretations than I previously thought.
So my question is: what is the reason for this horror? When is this rule actually necessary?
P.S. Sorry for the poorly worded title, please, feel free to change it!
Since this question is tagged language-lawyer, the direct answer is that, from [stmt.ambig]:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.
And, similarly, for functions, in [dcl.ambig.res]:
The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration.
Hence:
Why oh why is std::string("foo") so different from std::string(foo)
The former cannot be a declaration. The latter can be a declaration, with a redundant set of parentheses. Thus, the former isn't a declaration and the latter is.
The underlying issue is that, grammaticaly, declarators can start with a ( which could make it indistinguishable from a function-style explicit type conversion. Rather than come up with arbitrary complex rules to try to determine what the user meant, the language just picks one, and it's easy enough for the user to fix the code to actually do what he meant.

Does this line declare a function? C++

I was reading litb's question about SFINAE here and I was wondering exactly what his code is declaring. A simpler (without the templates) example is below:
int (&a())[2];
What exactly is that declaring? What is the role of the &? To add to my confusion, if I declare the following instead
int b()[2];
I get an error about declaring a function that returns an array, while the first line has no such error (therefore, one would think the first declaration is not a function). However, if I try to assign a
a = a;
I get an error saying I'm attempting to assign the function a... so now it is a function. What exactly is this thing?
There's these awesome programs called cdecl and c++decl. They're very helpful for figuring out complicated declarations, especially for the byzantine forms that C and C++ use for function pointers.
tyler#kusari ~ $ c++decl
Type `help' or `?' for help
c++decl> explain int (&a())[2]
declare a as function returning reference to array 2 of int
c++decl> explain int b()[2]
declare b as function returning array 2 of int
a returns a reference, b does not.
For future reference, you may find this link helpful when you have a particularly difficult C/C++ declaration to decipher:
How To Read C Declarations
For completeness, I will repeat what others have said to directly answer your question.
int (&a())[2];
...declares a to be a zero-argument function which returns a reference to an integer array of size 2. (Read the basic rules on the link above to have a clear understanding of how I came up with that.)
int b()[2];
...declares b to be a zero-argument function which returns an integer array of size two.
Hope this helps.
int (&a())[2];
It declares a symbol a that is a function that takes no arguments and returns a reference to a two-element array of integers.
int b()[2];
This declares a symbol b that is a function that takes no arguments and returns a two-element array of integers... this is impossible by the design of the language.
It is relatively simple: get an operator precedence chart, start the symbol name (a) and start applying the operators as you see from their precedence. Write down after each operation applied.