Ternary operator compilation - c++

Why does this giving compilation problem at bold line?
#include<iostream>
static int i = 10;
int main() {
**(i) ? (std::cout << "First i = " << i << std::endl) : ( i = 10);**
std::cout << "Second i = " << i << std::endl;
}
Compilation message:
test.c:8: error: invalid conversion from ‘void*’ to ‘int’

Your usage of the ternary operator is a bit weird: based on the value of i, you either print something to std::cout or assign a new value to it. Those actions don't share a connection through the return value of an expression, so don't do it like this. When using the ternary operator, it's best to stay closer to its intended purpose: a short notation for two possible expressions with a dispatch based on a simple predicate. Example:
const int n = i == 0 ? 42 : 43;
Your code should look like this:
if (i == 0)
i = 10;
else
std::cout << "First i = " << i << "\n";
The reason the original snippet did not compile is that there is no common return type of the ternary operator. "Common" means that both expressions can be converted to the return type. E.g., in const int n = i == 0 ? 42 : 43; the return type is int.

The problem comes from the fact that the return values of the expressions in your conditional operator (ternary operator) (std::ofstream in the case of the std::cout ..., and int for i = 10) are incompatible and therefore the conditional operator is ill-formed. Please check the rules for return type of the conditional operator.
In this case, just use a normal conditional:
if (i)
std::cout << "First i = " << i << std::endl;
else
i = 10;

Related

Output of Cout function in C++ [duplicate]

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?
The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).
Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;
By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.

I have a problem with the '?' operator. Why doesn't this line do what it should? [duplicate]

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?
The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).
Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;
By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.

Mistake with streaming and conditional operators

I recently came across a bug in my code, which I think might be a common mistake. I've generalized the mistake, and I'd like to understand why this does not generate a compiler warning or error. Thanks in advance.
The mistake is the following use of a conditional operator and streaming operator to cout:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2;
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 0
// i = 1
I'm assuming the first number printed 0 is the numeric representation of false. I'm not sure how the compiler interprets the rest. The array[i++] is getting evaluated because i has been incremented. This must be valid syntax, but the interpretation is not at all expected. Or is it?
For those who made the same mistake but do not know the fix, the corrected code has parentheses around the conditional operator:
int i=0;
int array[] = {1};
std::cout << (false ? array[i++] : 2);
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 2
// i = 0
Also, calling the streaming operator after the conditional operation would have generated a compiler error:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2 << std::endl;
std::cout << std::endl << "i = " << i << std::endl;
// fails to compile
// error: invalid operands of types 'int' and '<unresolved overloaded function type>' to binary 'operator<<'
I'm assuming the first number printed 0 is the numeric representation of false.
Correct.
I'm not sure how the compiler interprets the rest.
? : is the ternary conditional operator. The first subexpression (std::cout << false) is evaluated as a boolean, and if it is true, then the middle subexpression is evaluated (array[i++]), otherwise the last subexpression is evaluated (2).
std::cout is of type std::ostream. The stream insertion operator returns the stream itself. The stream has a conversion operator to boolean (since C++11; prior the conversion operator is to a void pointer, which has the same behaviour in this case). The behaviour of the conversion operator is:
Returns true if the stream has no errors and is ready for I/O operations.
Since there was no errors with the output stream, the conversion returns true, and therefore the middle subexpression (array[i++]) is evaluated.
I'd like to understand why this does not generate a compiler warning or error.
Because there is no error and (arguably) nothing to warn about. You may have intended to write something else, but what you did write is a valid program and the compiler cannot read your mind to find out that this is not what you had intended.
Note that if you removed any side effects from the ternary results: std::cout << false ? array[i] : 2;, then a compiler would likely warn you because the top level expression now has no side-effects.
P.S. Clang does warn about your program if you've enabled warnings:
main.cpp:7:20: warning: operator '?:' has lower precedence than '<<'; '<<' will be evaluated first [-Wparentheses]
std::cout << false ? array[i++] : 2;
~~~~~~~~~~~~~~~~~~ ^
main.cpp:7:20: note: place parentheses around the '<<' expression to silence this warning
std::cout << false ? array[i++] : 2;
^
main.cpp:7:20: note: place parentheses around the '?:' expression to evaluate it first
std::cout << false ? array[i++] : 2;
int i = 0;
std::cout << false ? array[i++] : 2;
The result of std::cout.operator<<(bool) converts to boolean true if std::cout is not in error, fail ... state. i++ gets evaluated and the whole statement yields array[0].

Conditional operator used in cout statement

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?
The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).
Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;
By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.

operator << : std::cout << i << (i << 1);

I use the stream operator << and the bit shifting operator << in one line.
I am a bit confused, why does code A) not produce the same output than code B)?
A)
int i = 4;
std::cout << i << " " << (i << 1) << std::endl; //4 8
B)
myint m = 4;
std::cout << m << " " << (m << 1) << std::endl; //8 8
class myint:
class myint {
int i;
public:
myint(int ii) {
i = ii;
}
inline myint operator <<(int n){
i = i << n;
return *this;
}
inline operator int(){
return i;
}
};
thanks in advance
Oops
Your second example is undefined behavior.
You have defined the << operator on your myint class as if it were actually <<=. When you execute i << 1, the value in i is not modified, but when you execute m << 1, the value in m is modified.
In C++, it is undefined behavior to both read and write (or write more than once) to a variable without an intervening sequence point, which function calls and operators are not, with respect to their arguments. It is nondeterministic whether the code
std::cout << m << " " << (m << 1) << std::endl;
will output the first m before or after m is updated by m << 1. In fact, your code may do something totally bizarre, or crash. Undefined behavior can lead to literally anything, so avoid it.
One of the proper ways to define the << operator for myint is:
myint operator<< (int n) const
{
return myint(this->i << n);
}
(the this-> is not strictly necessary, just my style when I overload operators)
Because int << X returns a new int. myint << X modifies the current myint. Your myint << operator should be fixed to do the former.
The reason you're getting 8 for the first is that apparently m << 1 is called first in your implementation. The implementation is free to do them in any order.
Your << operator is in fact a <<= operator. If you replace the line with
std::cout << i << " " << (i <<= 1) << std::endl; //8 8
you should get 8 8.
since m is a myInt your second example could be rewritten as:
std::cout << m << " " << (m.operator<<( 1)) << std::endl;
The order of evaluation for the subexpressions m and (m.operator<<( 1)) is unspecified, so there's no saying which "m" you'll get for the 1'st expression that m is used in (which is a simple m expression). So you might get a result of "4 8" or you might get "8 8".
Note that the statement doesn't result in undefined behavior because there are sequence points (at least one function call) between when m is modified and when it's 'read'. But the order of evaluation of the subexpressions is unspecified, so while the compiler has to produce a result (it can't crash - at least not legitimately), there's no saying which of the two possible results it should produce.
So the statement is about as useful as one that has undefined behavior, which is to say it's not very useful.
Well (m << 1) is evaluated before m and therefore m holds 8 already, as in your operator<< you overwrite your own value.
This is wrong behaviour on your side, the operator<< should be const and not change your object.
Because the << operator of myint modifies its lhs. So after evaluating m << 1, m will actually have the value 8 (while i << 1 only returns 8, but does not make i equal to 8). Since it is not specified whether m<<1 executes before cout << m (because it's not specified in which order the arguments of a function or operator are evaluated), it is not specified whether the output will be 8 8 or 4 8.
The C++ language does not define the order of evaluation of operators. It only defines their associativity.
Since your results depend on when the operator<< function is evaluated within the expression, the results are undefined.
Algebraic operator $ functions should always be const and return a new object:
inline myint operator <<(int n) const { // ensure that "this" doesn't change
return i << n; // implicit conversion: call myint::myint(int)
}