Disclaimer
I'm not entirely sure if this is the right SE for this, but I'll start here anyway.
Background
I was reading this question earlier and was looking at this code snippet in one of the answers
auto z = [&](){ static auto cache_x = x;
static auto cache_y = y;
static auto cache_result = x + y;
if (x == cache_x && y == cache_y)
return cache_result;
else
{
cache_x = x;
cache_y = y;
cache_result = x + y;
return cache_result;
}
};
Personally, I would be inclined to rewrite it as follows, with a single return statement
auto z = [&](){ static auto cache_x = x;
static auto cache_y = y;
static auto cache_result = x + y;
if (x == cache_x && y == cache_y)
{
}
else
{
cache_x = x;
cache_y = y;
cache_result = x + y;
}
return cache_result;
};
but this leaves a blank body for the if part.
We could rewrite the if/else to just be if(!(x == cache_x && y == cache_y)) but this runs the risk of being misunderstood (and can get messy).
My Question
What is the more accepted way of writing something like this, should we
have multiple return statements
leave the body of the if blank
rewrite the if condition to be the negated version
something else
Please note, I usually code in Java whereas the sample code is in C++. I am interested in the generally accepted way of doing things, as opposed to specific C++ constructs/methods.
I would be inclined to rewrite it […] with a single return statement
That's my preference also. You can get there more clearly by reversing the condition for the branch:
auto z = [&](){
static auto cache_x = x;
static auto cache_y = y;
static auto cache_result = x + y;
if (!(x == cache_x && y == cache_y)) {
cache_x = x;
cache_y = y;
cache_result = x + y;
}
return cache_result;
};
In general, if there's a branching logic (in this case, the if ... else ...) with one branch empty, try to rewrite it without that empty branch at all.
Related
This question already has answers here:
C++ initialize variable based on condition [closed]
(4 answers)
How to let a variable be dependent on other variables inside a class?
(6 answers)
How to initialize a static variable with another static variable?
(1 answer)
Closed 2 years ago.
For example, can I define a variable "z" in terms of variables I already defined called "x" and "y" (yes I know these are horrible naming conventions but it's an example). Like this:
int x = 0;
int y = 0;
int z = x * y;
Can you do something like that and just go on with your program or will you get error messages?
You may be interested in lambdas:
int x = 0;
int y = 0;
auto z = [&x, &y](){ return x * y; };
This code does exactly what you are requesting: calling the z() function would always give you the result that is the multiplication of the x and y variables:
int v = z();
assert(v == x * y);
Even if x or y change you would always get their multiplication:
int x = 0;
int y = 0;
auto z = [&x, &y](){ return x * y; };
assert(z() == 0);
x = 1;
y = 2;
assert(z() == 2);
can I define a variable "z" in terms of variables I already defined called "x" and "y"
int z = x * y;
Totally possible to define z that way. Most if not all languages should allow that basic definition. Except, perhaps you have to be careful with overflow issue. If later in your program you may assign x and y to very large value, then z could overflow. It may be better to do:
long long z = x * y;
Yes, you can.
Also,
int x = 1, y = x;
int z=x*y;
y = x; is possible.
How to find the smallest float/double number x which satisfies x + d = y given d and y?
(iiuc this is theoretically solved via setting fesetround (FE_DOWNWARD) and just doing y - d but in clang/Xcode I got a warning that FENV_ACCESS isn't supported and in practice found that it didn't work)
So, so far I made this:
// Find minimum x value so that x + d = y
template<typename T, bool supportDenormals = false>
T subtractMost (const T y, const T d)
{
T x = y - d;
while (true)
{
const T nextX =
x == 0 && !supportDenormals
? -std::numeric_limits<T>::min()
: nextafter (x, -std::numeric_limits<T>::infinity());
if (nextX + d != y)
return x;
T step = x - nextX;
while (true)
{
const T nextStep = step + step;
if (x - nextStep + d != y)
break;
step = nextStep;
}
x -= step;
}
}
Which does quite a lot of actions to find the result, but I wonder:
Is there's a more efficient solution or a more standard way to achieve this?
Why this code produce 1? Someone, describe it for me pls.
#include <iostream>
using namespace std;
int main(){
int x = 0;
int y = 0;
if (x++&&y++){
y += 2;
}
cout << x + y << endl;
return 0;
}
Initially x and y are 0
Therefore x++ evaluates to false, and the second operand of && is never evaluated. x++ does increment x to 1. Since the condition is false, the conditional branch is not entered.
x + y is 1 + 0 which equals 1
user2079303 explains nicely (+1 by me already), as extension, I'll go a little more into detail:
if(x++) evaluates the value of x before the incrementation, so this little piece of code is equivalent to the following (need to buffer the old value!):
int tmp = x;
x++;
if(tmp)
Be aware that within c && cc, the second condition cc is not evaluated any more if c is already false! So if(x && y) is equivalent to
if(x)
{
if(y)
{
// ...
}
}
Putting all this together, your code is equivalent to this variant, where I separated the if clause into code lines each one containing only one single instruction:
int x = 0;
int y = 0;
int tmp = x;
x++;
if(tmp)
{
tmp = y;
y++;
if(tmp)
y += 2;
}
Suppose, your output now is quite obvious...
Would this kind of variable assignment work?
double a = 2.0,
x, y, z = 0.5;
Would the second line of code work properly and initialize x, y, z each to 0.5?
Your code leaves x and y uninitialized. However, a slight rearrangement can save you from repeating an initial value:
double a = 2.0, x = 0.50, y = x, z = x;
Variables that are declared earlier in a declaration are in scope of later declarations.
This is sometimes particularly useful when evaluating one initializer may have a non-trivial runtime cost. For example, in the following nested loop where m is a multimap:
for (auto it = m.begin(), kt = it, e = m.end(); it != e; it = kt)
{ // ^^^^^^^^^^^^^^^^^^^^^^^
// handle partition
for (; kt != e && kt->first == it->first; ++kt)
{
// ... handle equal-range
}
}
No, only z would be initialized .You have to write it like this:
double x = 0.50, y = x, z = x;
But you can write an assignment like this:
double x, y, z;
x = y = z = 0.50;
Simply No. Only z will be initialized.
If you try to print them afterwards
std::cout << a << " " << x << " " << y << " " << z;
you will get this kind of warning from the compiler:
warning: 'x' is used uninitialized in this function
For the sake of clarity I would use the second option that Rabbid76 suggested:
double x, y, z;
x = y = z = 0.50;
The second line of code:
double x;
x = 50.1;
actually has a return value. Usually, it is not caught, or used, but it is there. So x = 50.1 returns the value 50.1.
This implies that you could do:
double x,y,z;
x = y = z = 50.1;
And the value will make its way up the chain where x = y returns and the value isn't caught again. After that line is executed, x, y and z will all have the value 50.1.
If you want to assign to all three variables, write
x = y = z = 0.5;
which is equivalent to
x = (y = (z = 0.5));
The code that you present only assigns to z.
You can achieve what you want doing this:
x = y = z = 0.50;
You could do that in a single line like this:
double x = 0.5, y = 0.5, z = 0.5;
I have a code segment as follows:
if(a < b)
{
x = y;
return w;
}
/* all unrelated variables above*/
x = something;
y = something;
/*both x and y from above*/
x and y are global variables, and they are modified inside the if part, I need to assign y to x and then return w, or simply a constant.
I need to use a ternary operator to replace the if part:
I tried the following:
return (((a < b) ? (x = y, w) : 1), (x = something, y = something));
But, I don't seem to get the desired result. I know it is wrong. This is because I used the return stement from a similar expression, that is:
if(x < y)
return (x = y);
return 1;
Which I wrote as:
return ((x < y) ? x = y : 1);
But, how do I return a value, that involves a prior assignment of a completely different variable in a ternary operator?
The solution suggested by Mankarse:
return (a < b) ? (x = y, w) : (x = something, y = something, z);
Is actually equivalent to:
if (a < b) {
x = y;
return w;
}
/* all unrelated variables above*/
x = something;
y = something;
return z;
The second return statement is important.
You cannot conditionally return from the middle of an expression, because return is a statement, you have to return the whole expression. So it really depends on how you want to proceed after the assignment to the y. Or if you really need to change the order of execution in the middle of an expression, you can throw an exception, but that, I guess, would be too complicated in this case.
Put the code block inside a function.
function f(){
x = y;//assumes x, y and w are global.
return w;
}
Then use the function in the conditional statement.
(a < b) ? f() : "value to return if a>=b";
You don't need to put return before a conditional statement since automatically returns 1 of the value, depends on the evaluation of the condition.