Runtime behavior with "C++ most vexing parse" - c++

While trying to answer this question I found without () (which invokes "C++ most vexing parse") the output of g++ is 1 (Can be seen here: http://ideone.com/GPBHy), where as visual studio gives a linker error. I couldn't understand how the output can 1, any clues?

As the answers to the question already explain, due to the "Most Vexing Parse" the statement instead of defining an object named str with the two istream_iterators to specify its initializers, is parsed as a declaration of a function named str that returns a string.
So a simple version of the program resolves to, this online sample:
#include<iostream>
void doSomething()
{
}
void (*ptr)()=&doSomething;
int main()
{
std::cout << ptr << "\n";
std::cout << doSomething;
return 0;
}
Output:
1
1
Note that there is no overloaded operator << that takes an std::ostream and a function pointer as arguments, this is because there can be any number of user defined function types and ofcourse a standard overloaded api cannot account for them all.
Given that the compiler tries to find the best match among the existing overloads which happens to be bool (a function pointer is implicitly convertible to bool[#1]).
In particular,
basic_ostream& operator<< (bool& val );
Since the function pointer points to something and not null, the value is printed as 1.
[#1]C++03 4.12 Boolean conversions
1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool.

Related

what functionname().anotherfunctionname() means in C++ [duplicate]

This question already has answers here:
Method chaining in C++?
(2 answers)
Closed last month.
for example in C++ we use:
int a = 12;
typeid(a).name();
to get type of a variable
my question is what exactly typeid is (im nearly sure its a function but Clion shows nothing)
and if its a function how it inherites or something the name() function
i tried to get what type id is but Clion showed nothing (when suggestion pops up in Clion for example when u type na it shows the suggestion and it shows and f infront of name so i know its a function but for typeid its empty)
edit:
is there a way to make something similar?
nearly all 3 answers were really good i appreciate all of them
According to cppreference, typeid
refers to a std::type_info object representing the type type. If type is a reference type, the result refers to a std::type_info object representing the cv-unqualified version (since C++11) of the referenced type.
So typeid(x) returns a std::type_info object that has methods you can query:
https://en.cppreference.com/w/cpp/types/type_info
typeid is a bit special since it's a keyword, which is likely why you weren't able to find too much information regarding it on CLion. Similarly you won't be able to find much on other keywords like int or if.
Nonetheless, the result of using typeid(some_variable) would be an std::type_info(a perfectly fine class), which would allow you to continue calling member functions like .name().
The construct does the following: the first function call has a return value of an object, which has the second function name as a member function.
E.g. in a more generic context:
#include <iostream>
struct AnObject {
void anotherFunctionName() {
std::cout << "anotherFunctionName() member of AnObject was called" << std::endl;
}
};
AnObject aFunctionName() {
std::cout << "aFunctionName() was called, returning AnObject" << std::endl;
return AnObject();
}
int main() {
// Return an instance of AnObject, and call its member function:
aFunctionName().anotherFunctionName();
}
This will output:
aFunctionName() was called, returning AnObject
anotherFunctionName() member of AnObject was called

How to define a class type conversion to a pointer to function?

I am trying to understand more Class-type conversion. I am reading C++ primer 5ed. So I've tried this code:
int add(int x, int y) { return x + y;}
struct Foo
{
//operator(int(*)(int, int))(){return add;} // error
using pfn = int(*)(int, int);
operator pfn(){return add;} // OK
double value = 5.45;
};
int main()
{
cout << (int(*)(int, int))Foo()(5, 7) << endl; // why 1
cout << ((int(*)(int, int))Foo())(5, 7) << endl; // Ok 12
std::cout << "\nDone!\n";
}
So why I cannot directly define conversion for my class using the type int(*)(int, int) but I can with a type alias?
Why I get value 1 in the first statement which is erroneous and get it correct in the second statement using parenthesis?
I get the warning from first statement: Description Resource Path Location Type cast to pointer from integer of different size [-Wint-to-pointer-cast] main.cpp /MyCppProj line 31 C/C++ Problem
So why I cannot directly define conversion for my class using the type int(*)(int, int) but I can with a type alias?
The grammar for the "operator TYPE" name of a conversion function is much more restricted than a more general declarator or type-id. It doesn't allow parentheses at all, only a type specifier (like a type alias name, unsigned int, a class name, etc.), combinations of the *, &, &&, const and volatile tokens, and [[attributes]]. I can't say exactly why, but complicated declarations like that are tricky to write, read, and parse. Maybe there's a potential ambiguity in some case if more were allowed, or maybe they just didn't want to require compilers to have to figure this one out.
Also, if it were allowed, maybe the form would be operator int (*())(int, int); and not operator (int(*)(int, int))()? Or maybe that doesn't make sense either. See? Tricky.
Why I get value 1 in the first statement which is erroneous and get it correct in the second statement using parenthesis?
Function call syntax has higher precedence than C-style cast. So
(int(*)(int, int))Foo()(5, 7) // (1)
(int(*)(int, int)) (Foo()(5, 7)) // (2), same as (1)
((int(*)(int, int))Foo()) (5, 7) // (3), not the same
Expression (1) or (2) evaluates by first creating a temporary Foo. It's followed by function call syntax, and Foo doesn't define an operator(), but C++ will also check if it implicitly converts to a pointer or reference to function and it does, so the (5, 7) does the implicit conversion and calls the resulting pointer to add, giving 12. This is cast to the function pointer type, which has implementation-defined results. There is no operator<< declared for function pointers, but there is one for bool, and a function pointer can implicitly convert to bool. Presumably the result of the strange cast was not a null pointer value, so the end result is true, and you see the value 1. (If you had done std::cout << std::boolalpha earlier, you should see true or an appropriate translation instead.)
One piece of this, besides the operator precedence misunderstanding, is the dangers of a C-style cast, which can do very many different things, some not usually intended. Use static_cast<int(*)(int,int)>(Foo())(5,7) instead, and everything's fine. Or if we accidentally typed static_cast<int(*)(int,int)>(Foo()(5,7)) instead, the compiler gives an error about converting from int to int(*)(int,int), since only reinterpret_cast or C-style cast may do that.
I get the warning from first statement: Description Resource Path Location Type cast to pointer from integer of different size [-Wint-to-pointer-cast] main.cpp /MyCppProj line 31 C/C++ Problem
Even though the C-style cast forces the conversion from int to function pointer to be valid, the compiler is warning that int doesn't have enough bytes to represent a function pointer. It's assuming the int value earlier came from casting a function pointer to some numeric type, and this is meant to convert back, but whenever it was converted from a type large enough to int, the pointer value was lost.

c or c++: specify return type when calling a function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
casting unused return values to void
What is the purpose of (void) before a function call, for example
(void)func1();
I assume this is the same as simply calling func1();
Therefore is the (void) call simply to let other programmers know that the return type will be ignored, for instance if func1() had a return type of int, or does the compiler perhaps perform some optimizations on the function? Perhaps there is another reason behind it altogether - is it even legal C++ or perhaps is it a remnant of C seen in some legacy code.
Thanks
A cast to void can have semantic effect in one case: where a value is an operand of the comma operator and overrides the comma operator, a cast to void will suppress it:
struct S {
int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n'; // prints '0'
std::cout << ((void) S(), 42) << '\n'; // prints '42'
It prevents warning if some function are declared with attribute : "Warn if return value not used/checked"
Maybe a duplicate of Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result
Check the documentation of gcc : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result) for more details
It means very little. It is explicitly turning the line to a void expression, that is an expression that is only used for its side effects and whose value is discarded. So the lines
func1();
and
(void)func1();
will do the same thing. There could be some optimization that can be performed if the compiler knows the value of the expression is not used, but it is likely that compiler can figure it out with or without the explicit (void).
It could be used as a form of documentation where the programmer is trying to make it obvious that they are not using the value of the expression.
Another strange use is to allow the function of unknown return type to be used adjacent to the , operator as a sequence operator. Ie, decltype( f(), g() ) technique, where you want to say "f can be operated on with (), as can g, and I want this type to be the type that g() returns". However, if f() returns a type such that operator, is overloaded, the result will be unexpected.
So you do decltype( void(f()), g() ), and discard the return value of f() before invoking operator,, so you are guaranteed to get the built-in sequence operator instead of some unknown override type.

Why am I always getting output as 1 when printing a function?

I am wondering why I'm always getting output as 1 when I print this function. Here is the code:
#include <iostream>
using namespace std;
int main() {
int x(int());
cout << x; // 1
}
It always prints out one. Why? I was expecting it to output 0 as ints are defaulted to 0. So why 1?
int x(int());
is a case of "most vexing parse"; you think it's a declaration of an int (int x) initialized to the default value for ints (int()); instead, the compiler interpret it as a declaration of a function returning an int which takes as a parameter a (pointer to) function that takes no parameters and returns an int (you can get hairy declarations explained by this site, or gain some more understanding about C type declarations here).
Then, when you do:
cout << x;
x here decays to function pointer, but there's no overload of operator<< that takes a function pointer; the simplest implicit conversion that gives some valid overload of operator<< is to bool, and, since a function pointer cannot have a 0 (NULL) value, it is evaluated to true, which is printed as 1.
Notice that I'm not entirely sure that such a code should be compiled without errors - you are taking the address of a function that is only declared and not defined; it is true that it cannot be evaluated to anything other than true, but in line of principle you should get a linker error (here masked by the optimizer, that removes any reference to x, since it isn't actually used).
What you actually wanted is:
int x=int();
The function is being converted to bool and is being printed as a bool value. The function is at a non-zero address, and so the conversion produces true.
This is a standard conversion sequence consisting of a function-to-pointer conversion followed by a boolean conversion.
The sequence is followed because there is no better overloaded operator<<.

Use of (void) before a function call [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
casting unused return values to void
What is the purpose of (void) before a function call, for example
(void)func1();
I assume this is the same as simply calling func1();
Therefore is the (void) call simply to let other programmers know that the return type will be ignored, for instance if func1() had a return type of int, or does the compiler perhaps perform some optimizations on the function? Perhaps there is another reason behind it altogether - is it even legal C++ or perhaps is it a remnant of C seen in some legacy code.
Thanks
A cast to void can have semantic effect in one case: where a value is an operand of the comma operator and overrides the comma operator, a cast to void will suppress it:
struct S {
int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n'; // prints '0'
std::cout << ((void) S(), 42) << '\n'; // prints '42'
It prevents warning if some function are declared with attribute : "Warn if return value not used/checked"
Maybe a duplicate of Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result
Check the documentation of gcc : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result) for more details
It means very little. It is explicitly turning the line to a void expression, that is an expression that is only used for its side effects and whose value is discarded. So the lines
func1();
and
(void)func1();
will do the same thing. There could be some optimization that can be performed if the compiler knows the value of the expression is not used, but it is likely that compiler can figure it out with or without the explicit (void).
It could be used as a form of documentation where the programmer is trying to make it obvious that they are not using the value of the expression.
Another strange use is to allow the function of unknown return type to be used adjacent to the , operator as a sequence operator. Ie, decltype( f(), g() ) technique, where you want to say "f can be operated on with (), as can g, and I want this type to be the type that g() returns". However, if f() returns a type such that operator, is overloaded, the result will be unexpected.
So you do decltype( void(f()), g() ), and discard the return value of f() before invoking operator,, so you are guaranteed to get the built-in sequence operator instead of some unknown override type.