Logical negation and assignment operator in C/C++? - c++

Is there a more concise way to write the second line of this function without repeating a reduntantly?
void myfunc()
{
bool a = false; // Assume that this won't alway be hardcoded to false.
a = !a;
}

Is there a more concise way to write the second line of this function without repeating a reduntantly?
! is an unary operator, you cannot associate it with = if this is what you expected.
But you can do something like a ^= true;, this is not a more concise way but this is without repeating a redundantly. Anyway this is not a good way to do contrarily to a = !a; which is much more readable

Well, I don't really see the value of doing so, but you could use xor or a simple decrement. Both of these work.
a ^= 1;
a--;
Then you won't have to repeat a.
But if you want it to be very clear, consider using a function:
void flip(bool *b)
{
(*b)--;
}
bool b = true;
flip(&b);
In C++, you can use references
void flip(bool &b)
{
b--;
}
bool b = true;
flip(b);
Or write a macro. Actually, macros are pretty handy for solving duplication problems. Although, I almost never use them for that, since it's simply rarely worth the effort. I wrote one macro to avoid duplication for malloc calls. Such a call typically look like this:
int *x = malloc(12 * sizeof *x);
You can avoid the duplication with this:
#define ALLOC(p, n) \
((p) = malloc((n) * sizeof *(p)))
But even this is something I hesitate to use.
To be honest, it's not really a problem worth solving. :)

The only possible answer is: unfortunately not.
The unary operator ! is actually concise enough, and any other trick would lead to unreadable code.
Any other shortcut form, for example for binary operators such as + or *:
a += 5;
b *= 7;
mantain the reference to the original meaning of theoperator: multiplication and addition respectively.
In your sentence:
without repeating a reduntantly
there's the wrong assumption that a is redundant in case the compiler could be instructed to negate a without repeating the variable name. No: it tells to people reading the code (even to yourself, for example an year later!) that the variable to be negated is a. And since C grammar doesn't define any syntactic sugar for logical negation operator, a is not redundant at all.

Related

Order of operations for bitwise operators (a & (a=1) strange behavior)?

I was messing around with some c++ code after learning that you cannot increment booleans in the standard. I thought incrementing booleans would be useful because I like compacting functions if I can and
unsigned char b = 0; //type doesn't really matter assuming no overflow
while (...) {
if (b++) //do something
...}
is sometimes useful to have, but it would be nice to not have to worry about integer overflow. Since booleans cannot take on any value besides 0 or 1, I thought that perhaps this would work. Of course, you could just have a boolean assigned to 1 after you do your operation but that takes an extra line of code.
Anyway, I thought about how I might achieve this a different way and I came up with this.
bool b = 0;
while (...)
if (b & (b=1)) ...
This turned out to always evaluate to true, even on the first pass through. I thought - sure, its just doing the bitwise operator from right to left, except that when I swapped the order, it did the same thing.
So my question is, how is this expression being evaluated so that it simplifies to always being true?
As an aside, the way to do what I wanted is like this I guess:
bool b = 0;
while (...) if (!b && !(b=1)) //code executes every time except the first iteration
There's a way to get it to only execute once, also.
Or just do the actually readable and obvious solution.
bool b = 0;
while (...) {
if (b) {} else {b=1;}
}
This is what std::exchange is for:
if (std::exchange(b, true)) {
// b was already true
}
As mentioned, sequencing rules mean that b & (b=1) is undefined behaviour in both C and C++. You can't modify a variable and read from it "without proper separation" (e.g., as separate statements).
There is no "strange behavior" here. The & operator, in your case is a bitwise arithmetic operator. These operator are commutative, so both operand must be evaluated before computing the resulting value.
As mentioned earlier, this is considered as undefined behavior, as the standard does not prevent computing + loading into a register the left operand, before doing the same to the second, or doing so in reverse order.
If you are using C++14 or above, you could use std::exchange do achieve this, or re-implement it quite easily using the following :
bool exchange_bool(bool &var, bool &&val) {
bool ret = var;
var = val;
return ret;
}
If you end up re-implementing it, consider using template instead of hard-coded types.
As a proper answer to your question :
So my question is, how is this expression being evaluated so that it simplifies to always being true?
It does not simplify, if we strictly follow the standard, but I'd guess you are always using the same compiler, which end up producing the same output.
Side point: You should not "compact" functions. Most of the time the price of this is less readability. This might be fine if you're the only dev working on a project, but on bigger project, or if you come back to your code later, that could be an issue. Last but not least, "compact" function are more error prone, because of their lack of readability.
If you really want shorter function, you should consider using sub-function that will handle part of the function computation. This would enable you to write short function, to quickly fix or update behavior, without impacting clarity.
I don't see what meaning you can assign to a "bitwise increment" operator. If I am right, what you achieve is just setting the low-order bit, which is done by b|= 1 (following the C conventions, this could have been defined as a unary b||, but the || was assigned another purpose). But I don't feel that this is a useful bitwise operation, and it can increment only once. IMO the standard increment operator is more bitwise.
If your goal was in fact to "increment" a boolean variable, i.e. set it to true (prefix or postfix), b= b || true is a way. (There is no "logical OR assignement" b||= true, and even less a "logical increment" b||||.)

How does c++ handle 0*(large expression)

Concerning speed, if I need to calculate a large expression, say:
switch1*(large expression 1)+switch2*(large expression 2)
Depending on my input, switch1 can be 0 or 1, as can switch2 be. What would be the quickest for c++ to do, making an if statement or write it down as above?
So, essentially you are asking about Short-Circuit Evaluation, and you are asking whether C++ does it for arithmetic expressions besides boolean expressions.
It is kind of hard to prove a negative, but as far as I know, C++ only does short-circuit evaluation for logical expressions, so there is no equivalent for arithmetic expressions. Also, I can think of plenty of code that would horribly break if arithmetic expressions were being evaluated in a short-circuit fashion, so I don't think that could ever be so.
Theoretically, the compiler could generate code to avoid computing the expression if it could show that it had no side-effects. But in practice, it's unlikely to add code to check if the value is zero because it has no reason to think that it will be.
On the other hand, logical operations (|| and &&) are guaranteed to short-circuit in C++. So you should use them.
result = 0;
if(switch1) {
result += large_expresion_1();
}
if(switch2)
result += large_expression2();
}
But if you are optimising "large expressions" be sure to check whether it's actually quicker to calculate them both then add them in a branchless manner. eg something like
result = ((-(uint64_t)(switch1)) & large_expression_1) + ((-(uint64_t)(switch2)) & large_expression_2);
A bunch of such bithacks are documented here:
https://graphics.stanford.edu/~seander/bithacks.html
Benchmark and separate to that, read the generated assembly language to find out what the compiler is actually doing for (or to) you.
switch1 can be 0 or 1, as can switch2 be
If switch1 and switch2 can really only have values of 0 or 1 then it would be better for them to be booleans rather than integers.
With boolean switches, your statement becomes:
result = (switch1 ? (large expression 1) : 0)
+ (switch2 ? (large expression 2) : 0)
It is the case that in this form, the expressions will be computed even if their result won't be used. A simple and clear way to avoid wasted computation is the obvious one:
result = 0;
if(switch1) {
result += large expression 1;
}
if(switch2) {
result += large expression 2;
}
You could tidy this up by extracting methods, into which you pass the switches:
result = guardedLargeExpression1(switch1, otherparams1)
+ guardedLargeExpression2(switch2, otherparams2);
... with ...
int guardedLargeExpression1(bool switch, foo params) {
if(switch) {
return 0;
}
return large expression(...);
}
You could also do clever stuff with pointers to functions:
int guardedFunctionCall(bool switch, int *functionptr(foo), foo arg) {
if(switch) {
return 0;
}
return (*functionptr)(arg);
}
... which is approaching the kind of thing you'd do in Java when you lazily evaluate code using a Supplier.
Or, since you're in C++ not C, you can do something more OO and actually use the C++ equivalent of Supplier: What is the C++ equivalent of a java.util.function.Supplier?
If depends on the exact conditions. CPU, compiler, the exact expressions.
An if can slow down a program, if if becomes a conditional jump in the assembly code, and the condition cannot be predicted.
If the conditional cannot be predicted, and the "large expressions" are actually simple, it may be faster to do the "multiply-way".
However, if the expressions are slow to calculate, or the if can be branch predicted perfectly (or it doesn't compile to a conditional jump), then I think the if way will be faster.
All in all, you should try both solutions, and check which is faster.

is it always faster to store multiple class calls in a variable?

If you have a method such as this:
float method(myClass foo)
{
return foo.PrivateVar() + foo.PrivateVar();
}
is it always faster/better to do this instead?:
float method(myClass foo)
{
float temp = foo.PrivateVar();
return temp + temp;
}
I know you're not supposed to put a call like foo.PrivateVar() in a for loop for example, because it evaluates it many times when you actually only need to use the value once (in some cases.
for (int i = 0; i < foo.PrivateInt(); i++)
{
//iterate through stuff with 'i'
}
from this I made the assumption to change code like the first example to that in the second, but then I've been told by people to not try to be smarter than the compiler! and that it could very well inline the calls.
I don't want to profile anything, I just want a few simple rules for good practice on this. I'm writing a demo for a job application and I don't want anyone to look at the code and see some rookie mistake.
That completely depends on what PrivateVar() is doing and where it's defined etc. If the compiler has access to the code in PrivateVar() and can guarantee that there are no side effects by calling the function it can do CSE which is basically what you've done in your second code example.
Exactly the same is true for your for loop. So if you want to be sure it's only evaluated once because it's a hugely expensive function (which also means that guaranteeing no side-effects get's tricky even if there aren't any) write it explicitly.
If PrivateVar() is just a getter, write the clearer code - even if the compiler may not do CSE the performance difference won't matter in 99.9999% of all cases.
Edit: CSE stands for Common Subexpression eliminiation and does exactly what it stands for ;) The wiki page shows an example for a simple multiplication, but we can do this for larger code constructs just as well, like for example a function call.
In all cases we have to guarantee that only evaluating the code once doesn't change the semantics, i.e. doing CSE for this code:
a = b++ * c + g;
d = b++ * c * d;
and changing it to:
tmp = b++ * c;
a = tmp + g;
d = tmp * d;
would obviously be illegal (for function calls this is obviously a bit more complex, but it's the same principle).

Is it good practice to use the comma operator?

I've recently (only on SO actually) run into uses of the C/C++ comma operator. From what I can tell, it creates a sequence point on the line between the left and right hand side operators so that you have a predictable (defined) order of evaluation.
I'm a little confused about why this would be provided in the language as it seems like a patch that can be applied to code that shouldn't work in the first place. I find it hard to imagine a place it could be used that wasn't overly complex (and in need of refactoring).
Can someone explain the purpose of this language feature and where it may be used in real code (within reason), if ever?
It can be useful in the condition of while() loops:
while (update_thing(&foo), foo != 0) {
/* ... */
}
This avoids having to duplicate the update_thing() line while still maintaining the exit condition within the while() controlling expression, where you expect to find it. It also plays nicely with continue;.
It's also useful in writing complex macros that evaluate to a value.
The comma operator just separates expressions, so you can do multiple things instead of just one where only a single expression is required. It lets you do things like
(x) (y)
for (int i = 0, j = 0; ...; ++i, ++j)
Note that x is not the comma operator but y is.
You really don't have to think about it. It has some more arcane uses, but I don't believe they're ever absolutely necessary, so they're just curiosities.
Within for loop constructs it can make sense. Though I generally find them harder to read in this instance.
It's also really handy for angering your coworkers and people on SO.
bool guess() {
return true, false;
}
Playing Devil's Advocate, it might be reasonable to reverse the question:
Is it good practice to always use the semi-colon terminator?
Some points:
Replacing most semi-colons with commas would immediately make the structure of most C and C++ code clearer, and would eliminate some common errors.
This is more in the flavor of functional programming as opposed to imperative.
Javascript's 'automatic semicolon insertion' is one of its controversial syntactic features.
Whether this practice would increase 'common errors' is unknown, because nobody does this.
But of course if you did do this, you would likely annoy your fellow programmers, and become a pariah on SO.
Edit: See AndreyT's excellent 2009 answer to Uses of C comma operator. And Joel 2008 also talks a bit about the two parallel syntactic categories in C#/C/C++.
As a simple example, the structure of while (foo) a, b, c; is clear, but while (foo) a; b; c; is misleading in the absence of indentation or braces, or both.
Edit #2: As AndreyT states:
[The] C language (as well as C++) is historically a mix of two completely different programming styles, which one can refer to as "statement programming" and "expression programming".
But his assertion that "in practice statement programming produces much more readable code" [emphasis added] is patently false. Using his example, in your opinion, which of the following two lines is more readable?
a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b;
Answer: They are both unreadable. It is the white space which gives the readability--hurray for Python!. The first is shorter. But the semi-colon version does have more pixels of black space, or green space if you have a Hazeltine terminal--which may be the real issue here?
Everyone is saying that it is often used in a for loop, and that's true. However, I find it's more useful in the condition statement of the for loop. For example:
for (int x; x=get_x(), x!=sentinel; )
{
// use x
}
Rewriting this without the comma operator would require doing at least one of a few things that I'm not entirely comfortable with, such as declaring x outside the scope where it's used, or special casing the first call to get_x().
I'm also plotting ways I can utilize it with C++11 constexpr functions, since I guess they can only consist of single statements.
I think the only common example is the for loop:
for (int i = 0, j = 3; i < 10 ; ++i, ++j)
As mentioned in the c-faq:
Once in a while, you find yourself in a situation in which C expects a
single expression, but you have two things you want to say. The most
common (and in fact the only common) example is in a for loop,
specifically the first and third controlling expressions.
The only reasonable use I can think of is in the for construct
for (int count=0, bit=1; count<10; count=count+1, bit=bit<<1)
{
...
}
as it allows increment of multiple variables at the same time, still keeping the for construct structure (easy to read and understand for a trained eye).
In other cases I agree it's sort of a bad hack...
I also use the comma operator to glue together related operations:
void superclass::insert(item i) {
add(i), numInQ++, numLeft--;
}
The comma operator is useful for putting sequence in places where you can't insert a block of code. As pointed out this is handy in writing compact and readable loops. Additionally, it is useful in macro definitions. The following macro increments the number of warnings and if a boolean variable is set will also show the warning.
#define WARN if (++nwarnings, show_warnings) std::cerr
So that you may write (example 1):
if (warning_condition)
WARN << "some warning message.\n";
The comma operator is effectively a poor mans lambda function.
Though posted a few months after C++11 was ratified, I don't see any answers here pertaining to constexpr functions. This answer to a not-entirely-related question references a discussion on the comma operator and its usefulness in constant expressions, where the new constexpr keyword was mentioned specifically.
While C++14 did relax some of the restrictions on constexpr functions, it's still useful to note that the comma operator can grant you predictably ordered operations within a constexpr function, such as (from the aforementioned discussion):
template<typename T>
constexpr T my_array<T>::at(size_type n)
{
return (n < size() || throw "n too large"), (*this)[n];
}
Or even something like:
constexpr MyConstexprObject& operator+=(int value)
{
return (m_value += value), *this;
}
Whether this is useful is entirely up to the implementation, but these are just two quick examples of how the comma operator might be applied in a constexpr function.

Is !! a safe way to convert to bool in C++?

[This question is related to but not the same as this one.]
If I try to use values of certain types as boolean expressions, I get a warning. Rather than suppress the warning, I sometimes use the ternary operator (?:) to convert to a bool. Using two not operators (!!) seems to do the same thing.
Here's what I mean:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
So, does the double-not technique really do the same thing? Is it any more or less safe than the ternary technique? Is this technique equally safe with non-integral types (e.g., with void * or double for T)?
I'm not asking if !!t is good style. I am asking if it is semantically different than t ? true : false.
The argument of the ! operator and the first argument of the ternary operator are both implicitly converted to bool, so !! and ?: are IMO silly redundant decorations of the cast. I vote for
b = (t != 0);
No implicit conversions.
Alternatively, you can do this: bool b = (t != 0)
Careful!
A boolean is about truth and falseness.
An integer is about whole numbers.
Those are very distinct concepts:
Truth and falseness is about deciding stuff.
Numbers are about counting stuff.
When bridging those concepts, it should be done explicitly. I like Dima's version best:
b = (t != 0);
That code clearly says: Compare two numbers and store the truth-value in a boolean.
All valid techniques, all will generate the same code.
Personally, I just disable the warning so I can use the cleanest syntax. Casting to a bool is not something I'm worried about doing accidentally.
Yes it is safe.
0 is interpreted as false, everthing else is true,
hence !5 comes out as a false
!0 comes out as true
so !!5 comes out as true
I would not use:
bool b = !!t;
That is the least readable way (and thus the hardest to maintain)
The others depend on the situation.
If you are converting to use in a bool expression only.
bool b = t ? true : false;
if (b)
{
doSomething();
}
Then I would let the language do it for you:
if (t)
{
doSomething();
}
If you are actually storing a boolean value. Then first I would wonder why you have a long in the first places that requires the cast. Assuming you need the long and the bool value I would consider all the following depending on the situation.
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
Summary:
Use what provides the most meaning for the context you are in.
Try and make it obvious what you are doing
I recommend never suppressing that warning, and never using a c cast (bool) to suppress it. The conversions may not always be called as you assume.
There is a difference between an expression that evaluates to true and a boolean of that value.
Both !! and ternary take getting used to, but will do the job similarly, if you do not want to define internal types with overloaded casts to bool.
Dima's approach is fine too, since it assigns the value of an expression to a bool.
If you're worried about the warning, you can also force the cast: bool b = (bool)t;
I really hate !!t!!!!!!. It smacks of the worst thing about C and C++, the temptation to be too clever by half with your syntax.
bool b(t != 0); // Is the best way IMHO, it explicitly shows what is happening.
Comparison to 0 doesn't work so well.
Which comes back -- why !! vs. ternary?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok
!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.
I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.
Disable the warning.
Write for clarity first; then profile; then optimize for speed, where required.
!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:
c = 3 + !!extra; //3 or 4
(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing
bool b = !!extra;
makes as much sense as:
if (!!extra) { ... }
I recommend to use
if (x != 0)
or
if (x != NULL)
instead of if(x); it's more understandable and readable.
The double not feels funny to me and in debug code will be very different than in optimized code.
If you're in love with !! you could always Macro it.
#define LONGTOBOOL(x) (!!(x))
(as an aside, the ternary operator is what I favor in these cases)
I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.