I want to use ternary operator("? : ") as if statement statement.To be precise I want to do something like this,if(temp>0) so increment 'i' else do nothing.
temp?i++:WHAT_SHOULD_COME_HERE_SO_NO_CHANGES_ARE_MADE_ANYWHERE
Answer
Strictly speaking, you can't do this:
(boolean expression) ? (returning expression) : /* no-op */;
Something has to go in the third operand. However, you can make that "something" behaviorally equivalent to a no-op in terms of the post-conditions of evaluating the ternary operator. See below.
Explanation
The ternary operator must return a value, and the type is deduced as the most derived type that is a supertype of the return type of each of the second and third operands. So if the third operand is a blank expression (i.e. it returns nothing), then the compiler cannot deduce a return type for the operator as a whole. Thus, it will not compile.
Solution
Using the ternary operator:
If you really wanted to, this is how you might do it using the ternary operator:
i = temp>0 ? i+1 : i;
or
temp>0 ? ++i : i;
Preferred syntax:
Although if all you're looking for is a one-liner, then the following syntax is preferred:
if (temp>0) ++i;
This will work:
(void) ((temp>0)?i++:0);
Note that the (void) does not change the behavior of the code; rather it is there to indicate to the reader (and/or any style checking programs you might invoke in the future) that the result of the expression is being deliberately discarded. Without it you may get warnings from the compiler and/or other programmers suspecting a bug and trying to "fix" your code.
Actually, you may get that anyway, since the above is a very unusual way to express what you are trying to do. The code will be easier for others to understand and maintain if you instead use the traditional form:
if (temp>0) i++;
The ternary operator is used in an expression. As such, the entire expression must evaluate to a single value. This means that you must supply both the "if" and "else" clauses. There is no way to leave the "else" part blank.
In addition, embedding an increment operator within an expression such as this is inadvisable since the consequences of the side-effect are so error-prone.
you can:
int temp = 20, i = 0;
(temp)? i++: i;
cout << i << endl;
Related
I just came onto a project with a pretty huge code base.
I'm mostly dealing with C++ and a lot of the code they write uses double negation for their boolean logic.
if (!!variable && (!!api.lookup("some-string"))) {
do_some_stuff();
}
I know these guys are intelligent programmers, it's obvious they aren't doing this by accident.
I'm no seasoned C++ expert, my only guess at why they are doing this is that they want to make absolutely positive that the value being evaluated is the actual boolean representation. So they negate it, then negate that again to get it back to its actual boolean value.
Is this correct, or am I missing something?
It's a trick to convert to bool.
It's actually a very useful idiom in some contexts. Take these macros (example from the Linux kernel). For GCC, they're implemented as follows:
#define likely(cond) (__builtin_expect(!!(cond), 1))
#define unlikely(cond) (__builtin_expect(!!(cond), 0))
Why do they have to do this? GCC's __builtin_expect treats its parameters as long and not bool, so there needs to be some form of conversion. Since they don't know what cond is when they're writing those macros, it is most general to simply use the !! idiom.
They could probably do the same thing by comparing against 0, but in my opinion, it's actually more straightforward to do the double-negation, since that's the closest to a cast-to-bool that C has.
This code can be used in C++ as well... it's a lowest-common-denominator thing. If possible, do what works in both C and C++.
The coders think that it will convert the operand to bool, but because the operands of && are already implicitly converted to bool, it's utterly redundant.
Yes it is correct and no you are not missing something. !! is a conversion to bool. See this question for more discussion.
It's a technique to avoid writing (variable != 0) - i.e. to convert from whatever type it is to a bool.
IMO Code like this has no place in systems that need to be maintained - because it is not immediately readable code (hence the question in the first place).
Code must be legible - otherwise you leave a time debt legacy for the future - as it takes time to understand something that is needlessly convoluted.
It side-steps a compiler warning. Try this:
int _tmain(int argc, _TCHAR* argv[])
{
int foo = 5;
bool bar = foo;
bool baz = !!foo;
return 0;
}
The 'bar' line generates a "forcing value to bool 'true' or 'false' (performance warning)" on MSVC++, but the 'baz' line sneaks through fine.
Legacy C developers had no Boolean type, so they often #define TRUE 1 and #define FALSE 0 and then used arbitrary numeric data types for Boolean comparisons. Now that we have bool, many compilers will emit warnings when certain types of assignments and comparisons are made using a mixture of numeric types and Boolean types. These two usages will eventually collide when working with legacy code.
To work around this problem, some developers use the following Boolean identity: !num_value returns bool true if num_value == 0; false otherwise. !!num_value returns bool false if num_value == 0; true otherwise. The single negation is sufficient to convert num_value to bool; however, the double negation is necessary to restore the original sense of the Boolean expression.
This pattern is known as an idiom, i.e., something commonly used by people familiar with the language. Therefore, I don't see it as an anti-pattern, as much as I would static_cast<bool>(num_value). The cast might very well give the correct results, but some compilers then emit a performance warning, so you still have to address that.
The other way to address this is to say, (num_value != FALSE). I'm okay with that too, but all in all, !!num_value is far less verbose, may be clearer, and is not confusing the second time you see it.
Is operator! overloaded?
If not, they're probably doing this to convert the variable to a bool without producing a warning. This is definitely not a standard way of doing things.
!! was used to cope with original C++ which did not have a boolean type (as neither did C).
Example Problem:
Inside if(condition), the condition needs to evaluate to some type like double, int, void*, etc., but not bool as it does not exist yet.
Say a class existed int256 (a 256 bit integer) and all integer conversions/casts were overloaded.
int256 x = foo();
if (x) ...
To test if x was "true" or non-zero, if (x) would convert x to some integer and then assess if that int was non-zero. A typical overload of (int) x would return only the LSbits of x. if (x) was then only testing the LSbits of x.
But C++ has the ! operator. An overloaded !x would typically evaluate all the bits of x. So to get back to the non-inverted logic if (!!x) is used.
Ref Did older versions of C++ use the `int` operator of a class when evaluating the condition in an `if()` statement?
As Marcin mentioned, it might well matter if operator overloading is in play. Otherwise, in C/C++ it doesn't matter except if you're doing one of the following things:
direct comparison to true (or in C something like a TRUE macro), which is almost always a bad idea. For example:
if (api.lookup("some-string") == true) {...}
you simply want something converted to a strict 0/1 value. In C++ an assignment to a bool will do this implicitly (for those things that are implicitly convertible to bool). In C or if you're dealing with a non-bool variable, this is an idiom that I've seen, but I prefer the (some_variable != 0) variety myself.
I think in the context of a larger boolean expression it simply clutters things up.
If variable is of object type, it might have a ! operator defined but no cast to bool (or worse an implicit cast to int with different semantics. Calling the ! operator twice results in a convert to bool that works even in strange cases.
This may be an example of the double-bang trick (see The Safe Bool Idiom for more details). Here I summarize the first page of the article.
In C++ there are a number of ways to provide Boolean tests for classes.
An obvious way is the operator bool conversion operator.
// operator bool version
class Testable {
bool ok_;
public:
explicit Testable(bool b = true) : ok_(b) {}
operator bool() const { // use bool conversion operator
return ok_;
}
};
We can test the class as thus:
Testable test;
if (test) {
std::cout << "Yes, test is working!\n";
}
else {
std::cout << "No, test is not working!\n";
}
However, operator bool is considered unsafe because it allows nonsensical operations such as test << 1; or int i = test.
Using operator! is safer because we avoid implicit conversion or overloading issues.
The implementation is trivial,
bool operator!() const { // use operator!
return !ok_;
}
The two idiomatic ways to test Testable object are
Testable test;
if (!!test) {
std::cout << "Yes, test is working!\n";
}
if (!test) {
std::cout << "No, test is not working!\n";
}
The first version if (!!test) is what some people call the double-bang trick.
It's correct but, in C, pointless here -- 'if' and '&&' would treat the expression the same way without the '!!'.
The reason to do this in C++, I suppose, is that '&&' could be overloaded. But then, so could '!', so it doesn't really guarantee you get a bool, without looking at the code for the types of variable and api.call. Maybe someone with more C++ experience could explain; perhaps it's meant as a defense-in-depth sort of measure, not a guarantee.
Maybe the programmers were thinking something like this...
!!myAnswer is boolean. In context, it should become boolean, but I just love to bang bang things to make sure, because once upon a time there was a mysterious bug that bit me, and bang bang, I killed it.
I am having confusion with the return value of post-increment and pre-increment operator.Whether it returns r-value or l-value.
#include<iostream>
using namespace std;
int main(){
int a=10;
cout<<++a++<<"\n";
}
The following code give a compile error.
error: lvalue required as increment operator
Why is there an error?
How does the compiler evaluates the expression ++a++?
The result of the post-increment expression, a++ is an rvalue; a temporary with the value that a had before incrementing. As an rvalue, you can use its value, but you can't modify it. Specifically, you can't apply pre-increment it, as the compiler says.
If you were to change the precedence to do the pre-increment first:
(++a)++
then this would compile: the result of pre-increment is an lvalue denoting the object that's been modified. However, this might have undefined behaviour; I'm not sure whether the two modifications and the various uses of the value are sequenced.
Summary: don't try to write tricky expressions with multiple side-effects.
Conceptually, the postfix ++ has higher precedence than prefix ++.
So a++ will be computed first. But this is not an lvalue (as it's the previous value of a). It therefore cannot be pre-incremented. Hence the compiler output.
More importantly though, the behaviour of the whole expression ++a++ is undefined due to their being no sequencing point in the expression.
Just for what it's worth (not much, IMO) if you make the a in question the proper type, it's possible to get this to compile and have defined behavior. The trick (and in this case it's a dirty, evil trick) is to overload the post-fix increment operator to return an lvalue:
class dirty_evil_trick {
int val;
public:
dirty_evil_trick() : val(0) {}
// to demonstrate, I'll just make postfix increment act like prefix increment.
dirty_evil_trick operator++(int) {
++val;
return *this;
}
dirty_evil_trick operator++() {
++val;
return *this;
}
operator int(){ return val; }
};
As implied by the name, this is (at least in my opinion) truly horrible code. We've made both the prefix and postfix increment operators act like prefix increment. So, for example, if we exercise it as follows:
int main(){
dirty_evil_trick a;
std::cout << ++a++;
}
...it should print out 2. And, since invoking the operator overload functions imposes ordering constraints, we should be able to count on that result with all conforming compilers.
I'll repeat once more though: this is not intended as advice about how you should write code. It's really just a demonstration of what the error message you got meant, and how you can write code that does let this actually work (or, at least compile and do something. Whether that qualifies as "working" is a whole 'nother question).
First of all, that's terrible programming style. Depending on your needs, you can easily write:
++a;
cout << a++ <<"\n";
or
a++;
cout << ++a <<"\n";
Coming to the compiler error...
Due to operator precedence, ++a++ is the same as ++(a++). However, a++ evaluates to an rvalue. Using the prefix increment operator on an rvalue is not allowed. That will be analogous to using ++10, which is not legal.
Let's say I have a C++ class with two functions like
class MyClass
{
bool Foo(int val);
bool Foo(string val);
}
Is it possible to use the ternary operator like this
MyClassInstance->Foo(booleanValue?24:"a string");
and have a different function of MyClass invoked depending on the value of booleanValue?
Not with the ternary operator. The type of a ternary expression is the common type of its second and third operands; if they have no common type you can't use it. So just use an ordinary if statement:
if (booleanValue)
MyClassInstance->Foo(24);
else
MyClassInstance->Foo("a string");
The type of a ternary conditional expression is the common type two which both operands are convertible. You can definitely not perform "dynamic overload resolution", as you seem to be suggesting.
Since there is no common type for int and char const *, the code won't even compile (as you surely noticed when you tested this).
(You may be thrilled to know that the ternary conditional is used precisely because of those semantics in the implementation of the std::common_type trait class template, together with decltype.)
(If the condition is known statically, such as sizeof(int) != 7, then you can use template specialization to write similar-looking code that does perform conditional overload resolution, but of course statically.)
No. To perform overload resolution the compiler will ask "what is the type of booleanValue?24:"a string"?". That question cannot be answered.
No, this is not permitted.
Overloads are compile-time, so it cannot work in runtime that way.
It is not common in code you would want to do exactly that, however sometimes with iostream there is a desire to do something like:
os << ( condition ? var1 : var2 )
where var1 and var2 have different types. That also doesn't work.
You could do:
MyClassInstance->Foo( booleanValue ? boost::any(24) : boost::any("a string") );
Can I use:
MyClass& MyClass::operator++ () {
a++; // private var of MyClass
return (*this);
}
Or it can be:
MyClass MyClass::operator++ ();
What's the difference?
Thanks for answers. I have another issue.
Many people do something like that:
MyClass& MyClass::operator++();
MyClass MyClass::operator++(int);
Isn't it illogical? Please give some examples if you can.
I know that the first version is pre-increment and the second is post-increment, but i ask why the first one returns reference but the second one not? It is in the same code (class), and the same use of the code.
No, you don't have to return the reference to your object when you overload the pre-increment operator. In fact you may return anything you'd like, MyClass, int, void, whatever.
This is a design issue -- you must ask yourself what is the most useful thing to the users of your class that you are able to return.
As a general rule, class operators are the most useful when they cause the least confusion, that is, when they operate the most like operators on basic types. In this case, the pre-increment operator on a basic type:
int i = 7;
j = ++i;
increments the variable and then returns the new value. If this is the only use you want MyClass to have, then returning a copy of your class is sufficient.
But, the pre-increment operator on a basic type actually returns an lvalue. So, this is legal:
int i = 7;
int *p = &++i;
If you want to support an operation like this, you must return a reference.
Is there a specific reason that you don't want to return a reference? Is that not a well-formed concept for your particular class? If so, consider returning void. In that case, this expression: ++myObject is legal, while this myOtherObject = ++myObject is not.
You can return whatever you want. void, reference to self, copy of self, something else. Whichever you prefer (or need).
If you plan using the ++ operator in chained expressions (like (++obj).something()) then return a reference. In you don't, then void is just fine.
Remember that in the end, operators are just like normal methods: you can do whatever you want with them, provided you respect their prototype.
For question two:
Prefix returns a reference, as expected.
Postfix returns a copy to be consistent with the behavior of the postfix operator(s).
Break it down simply to int:
int c = 0;
if(++c)
{
// true, prefix increments prior to the test
}
c = 0;
if(c++)
{
// false, c now == 1, but was incremented after the test
}
Implementing this behavior in a class requires a copy be returned because the postfix operator will have modified the state of the object.
If the program does not need true postfix operation, you are free of course to implement how you wish. While there are standard ways of writing these operators (that are understood by most C++ programmers), there's nothing actually stopping you from implementing this in different ways.
The argument provided about incorrect functionality surrounding (obj++)++ is not really important, as that code won't even compile for POD types (in Visual Studio 2010, at least), because for POD types, a copy is returned and that temporary copy cannot be used alone as an l-value.
However, for the prefix operator a reference is the preferred return as that allows the proper behavior for chaining the operation (++(++obj)).
Its not compulsory, but we should try to make operator overloading intuitive and it should work as per the operator which is being overloaded.
If we do
int i = 10;
i++ = 0
Then second statement is not allowed it says it requires lvalue as i++ denotes older state of i not a storage ...
while ++i = 0 perfectly works fine ..
so just to keep it in sync with actual operators prefix version had to return refence so that its return value may be treated as lvalue in expressions.
Yes, you should return by reference. No need for the parenthesis around *this.
EDIT: Replying to your comment... You don't have to return by reference. But in general we follow some guidelines which make our classes behave "as expected" when compared to the builtin semantics of such operators. You might wanna take a look at http://www.parashift.com/c++-faq-lite/operator-overloading.html.
Here is some code I'm writing in C++. There's a call to an addAVP() function
dMessage.addAVP(AVP_DESTINATION_HOST, peer->getDestinationHost() || peer->getHost());
which has two versions: one overloaded in the second parameter to addAVP(int, char*) and another to addAVP(int, int). I find the C++ compiler I use calls the addAVP(int, int) version which is not what I wanted since getDestinationHost() and getHost() both return char*.
Nonetheless the || operator is defined to return bool so I can see where my error is. Bool somehow counts as an integer and this compiles cleanly and calls the second addAVP().
Lately I'm using a lot of dynamically typed languages, i.e. lisp, where the above code is correct can be written without worries. Clearly, clearly the above code in C++ is a big error, but still have some questions:
Should I be using this kind of shortcut, i.e. using the ||-operator's return value, at all in C++. Is this compiler dependent?
Imagine that I really, really had to write the nice a || b syntax, could this be done cleanly in C++? By writing an operator redefinition? Without losing performance?
As a followup to my original request, or my own answer to 2 :-) I was thinking along the lines of using a class to encapsulate the (evil?) rawpointer:
class char_ptr_w {
const char* wrapped_;
public:
char_ptr_w(const char* wrapped) : wrapped_(wrapped) {}
char_ptr_w(char_ptr_w const& orig) { wrapped_=orig.wrapped(); }
~char_ptr_w() {}
inline const char* wrapped() const { return wrapped_; }
};
inline char_ptr_w operator||(char_ptr_w &lhs, char_ptr_w& rhs) {
if (lhs.wrapped() != NULL)
return char_ptr_w(lhs.wrapped());
else
return char_ptr_w(rhs.wrapped());
};
Then I could use:
char_ptr_w a(getDestinationHost());
char_ptr_w b(getHost());
addAVP(AVP_DESTINATION_HOST, a || b);
In which this addAVP would be overloaded for char_ptr_w. According to my tests, this generates at most the same assembly code as ternary a?b:c solution, particularly because of the NRVO optimization in the operator, which does not, in most compilers, call the copy-constructor (although you have to include it).
Naturally, in this particular example I agree that the ternary solution is the best. I also agree that operator redefinition is something to be taken with care, and not always beneficial. But is there anything conceptually wrong, in a C++ sense, with the above solution?
It is legal in C++ to overload the logic operators, but only if one or both of the arguments are of a class type, and anyway it's a very bad idea. Overloaded logic operators do not short circuit, so this may cause apparently valid code elsewhere in your program to crash.
return p && p->q; // this can't possibly dereference a null pointer... can it?
As you discovered, a bool is really an int. The compiler is picking the correct function for your footprint. If you want to keep similar syntax, you might try
char*gdh=0;
dMessage.addAVP(AVP\_DESTINATION\_HOST,
(gdh=peer->getDestinationHost()) ? gdh : peer->getHost());
I would strongly recommend against redefining the operator. From a maintenance perspective, this is very likely to confuse later developers.
Why are you using an "or" operator on two char pointers?
I am assuming that peer->getDestinationHost() or peer->getHost() can return a NULL, and you are trying to use the one that returns a valid string, right?
In that case you need to do this separately:
char *host = peer->getDestinationHost();
if(host == NULL)
host = peer->getHost();
dMessage.addAVP(AVP\_DESTINATION\_HOST, host);
It makes no sense to pass a boolean to a function that expects a char *.
In C++ || returns a bool, not one of its operands. It is usually a bad idea to fight the language.
1) Should I be using this kind of shortcut, i.e. using the ||-operator's return value, at all in C++. Is this compiler dependent?
It's not compiler dependent, but it doesn't do the same as what the || operator does in languages such as JavaScript or or in common lisp. It coerces it first operand to a boolean values, and if that operand is true returns true. If the first operand is false, the second is evaluated and coerced to a boolean value, and this boolean value is returned.
So what it is doing is the same as ( peer->getDestinationHost() != 0 ) || ( peer->getHost() != 0 ). This behaviour is not compiler dependent.
2) Imagine that I really, really had to write the nice a || b syntax, could this be done cleanly in C++? By writing an operator redefinition? Without losing performance?
Since you are using pointers to chars, you can't overload the operator ( overloading requires one formal parameter of a class type, and you've got two pointers ). The equivalent statement C++ would be to store the first value in a temporary variable and then use the ?: ternary operator, or you can write it inline with the cost of evaluating the first expression twice.
You could instead do something like:
dMessage.addAVP(AVP_DESTINATION_HOST, (peer->getDestinationHost())? peer->getDestinationHost() : peer->getHost());
This is not as neat as || but near to it.
Well, you're right about what the problem is with your code: a || b will return a bool, which is converted to int (0 for false, != 0 for true).
As for your questions:
I'm not sure whether the return value is actually defined in the standard or not, but I wouldn't use the return value of || in any context other than a bool (since it's just not going to be clear).
I would use the ? operator instead. The syntax is: (Expression) ? (execute if true) : (execute if false). So in your case, I'd write: (peer->getDestinationHost() =! NULL) ? peer->getDestinationHost() : peer->getHost(). Of course, this will call getDestinationHost() twice, which might not be desirable. If it's not, you're going to have to save the return value of getDestinationHost(), in which case I'd just forget about making it short and neat, and just use a plain old "if" outside of the function call. That's the best way to keep it working, efficient, and most importantly, readable.