branching depending on which of 3 numbers is smallest - c++

The solution is obvious, but this is question about nice solution.
(EDIT: by nice I mean e.g. 1) without code redudancy 2) without comprimising performance 3) without forcing programmer to make some unnecessary function or temporary variables )
Consider situation when I would like to execute 3 different blocks of code depending on which of numbers a,b,c is smallest.
The code would look like this:
if( a < b ){
if( a < c ){
// code block for "a is minimum" case
}else{
// code block for "c is minimum" case
}
}else{
if( b < c ){
// code block for "b is minimum" case
}else{
// code block for "c is minimum" case
}
}
What I don't like is that I have to copy the // code block for "c is minimum" case twice.
There are several solutions to that. E.g. I can put the block of code for "c is minimum" into an inline function or macro. But I don't like it (seems less clear to read).
Old school solution would be use goto like:
if( a < b ){
if( a < c ){
// code for "a is minimum" case
goto BRANCHE_END;
}
}else{
if( b < c ){
// code for "b is minimum" case
goto BRANCHE_END;
}
}
// code for "c is minimum" case
BRANCHE_END:
but people don't like to see goto (for good reason). On the other hand in this particular case it is even very well readable.
If the block of code would be independent function it can be written like
void myBranching( double a, double b, double c ){
if( a < b ){
if( a < c ){
// code for "a is minimum" case
return;
}
}else{
if( b < c ){
// code for "b is minimum" case
return;
}
}
// code for "c is minimum" case
return;
}
(which is actually almost the same as that goto) But in many cases similar block of code have to be part of more complex algorithm and it is inconvenient to put it inside function. Encapsulation in function would require passing many variables which are used both inside and outside ( e.g. see the use case below) .
Is there any control structure in C/C++ which would solve this in elegant way.
NOTE: Consider performance critical code. (e.g. ray-tracer, GLSL shader, physical simulation ). Anything which would add some unnecessary computational overhead is out of question.
Additional questions / comments
This is one of a few examples when I feel like Structured programming tie my hands, and that it is just subset of what is possible to do with jump instruction. Do you know other examples where algorithm would be more simple and clear using goto rather than standard control structures ?
can you imagine more complex branching where it would be necessary to copy some blocks of code even more times ?
EDIT : Use case
I think some confusion resulted from the fact that I did not specified context in which I want to use this. This is part of algorithm which raytrace regular triclinic 3D grid ( something like Bresenham's line algorithm in 3D, but the starting point is float (not aligned to center of any box) )
but please, do not focus on algorithm itself, it may be also wrong, I'm currently debugging it.
double pa,pb,pc,invPa,invPb,invPc,mda,mdb,mdc,tmax,t;
int ia,ib,ic;
// for shortness I don't show initialization of these variables
while( t<tmax ){
double tma = mda * invPa;
double tmb = mdb * invPb;
double tmc = mdc * invPc;
if( tma < tmb ){
if( tma < tmc ){ // a min
t += tma;
mda = 1;
mdb -= pb*tma;
mdc -= pc*tma;
ia++;
}else{ // c min
t += tmc;
mda -= pa*tmc;
mdb -= pb*tmc;
mdc = 1;
ic++;
}
}else{
if( tmb < tmc ){ // b min
t += tmb;
mda -= pa*tmb;
mdb = 1;
mdc -= pc*tmb;
ib++;
}else{ // c min
t += tmc;
mda -= pa*tmc;
mdb -= pb*tmc;
mdc = 1;
ic++;
}
}
// do something with ia,ib,ic,mda,mdb,mdc
}

You can solve this pretty easily with std::min and using the version that takes a std::initializer_list. You call min on the three variables to get the minimum and then you have three if statements to check the return against each of the variables.
void foo(int a, int b, int c)
{
int min = std::min({a, b, c});
if (min == a)
{
// a case
}
else if (min == b)
{
// b case
}
else
{
// c case
}
}

You don't have to nest conditionals by the way:
if(a <= b && a <= c) { /* a is the lowest */ }
else if(b <= c) { /* b is the lowest */ }
else { /* c is the lowest */ }
Note that the semantics of C++'s operator && is such that
if(a <= b && a <= c)
works roughly like
if(a <= b) if(a <= c)
(The difference is that the succeeding else clause, if any, covers both ifs simultaneously.) In the expression cond1 && cond2, if cond1 proves to be false then cond2 is never evaluated, at least, it does not have observable side-effects.
Sure we can make something more monstrous, with non-local exits, for example:
do {
if(a <= b) {
if(a <= c) {
// a is the lowest
break;
}
}
else if(b <= c) {
// b is the lowest
break;
}
// c is the lowest
}
while(0);
But in fact this construct, despite being incredibly taller, is logically equivalent to those three lines above (with Dieter's proposed edit).

Related

How to generate a boolean condition during runtime in C++?

I want to be able to generate a boolean condition during the runtime based on the states of some variables. My task looks simple at first. I have a large if () else if () statement what needs to determine if the number is in a certain range. It then does something depending on whether that number is inside that range.
Here's pseudocode to demonstrate what I want:
void fun(int num, int offset = 0) {
if (0...60) {
// do something
} else if (60...180) {
// do something else
} else if (180...240) {
} else if (240...360) {
}
}
The first if statement should work like this:
if (0 >= num && num <= 20) {
// do something
}
The caveat here is that in addition to int num, there is another parameter passed in, which I call the offset. The structure of the code here, including the do something inside the { } is the same. The only things that need to change are are ranges, based on the value of the offset. By the way, this is not a default parameter here, it is just pseudocode demonstrating what the value of int offset was passed in.
void fun(int num, int offset = 120) {
if (120...180) {
// do something
} else if (180...300) {
// do something else
} else if (300...360) {
} else if (360...120) {
}
}
That last else if () statement has been giving me some trouble.
} else if (360...120) {
}
What I'm actually trying to write here is:
} else if (num >= 360 || num <= 120) {
}
The reason for this is that my int num may have a value > 360. However, in that case for the purpose of my application it has to "wrap around" and be treated as a value 0...120.
This is for a mathematical application here. Whenever you have int num > 360, you go around the full circle and you end back at 0 where you started. So that is the effect which I want to achieve.
I don't want to write extra functions. I want my code to be generic because many different values for int num and int offset may be passed into my function. I want to generate the necessary conditions during the runtime based on the value of int offset.
The main problem here is that in the first situations, when int offset = 0 my condition is
} else if (240 >= num && num <= 360) {
}
However, for a different offset we wrap around and so I have to change the format of the entire condition! For example, when int offset = 120, as shown above:
} else if (num >= 360 || num <= 120) {
}
The problem is that in the first situation I had the && in the last else if (), but now I have the || to convey the same meaning. What I'm looking for is a way to be able to manipulate the operators inside the conditional statements as mere chars in a string, then "paste" the completed condition into the if () statements during the runtime!
What's even worse is that this "wrapping around" can occur inside any one of the if () statements, not just the last one. It is based on the value of the offset.
I can't use preprocessor tricks, because I want this to work during the runtime. Maybe it is possible to use function pointers or something for this, but I don't know how to do that. Please note that the ... above is not real C++ code, it is pseudocode! I'm aware that there is a "range-based" switch statement in C++, but I can't use that because of the "wrapping around" property mentioned above.

How to safely compare two unsigned integer counters?

We have two unsigned counters, and we need to compare them to check for some error conditions:
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a/2 > b) {
perror("Error happened!");
return -1;
}
The problem is that a and b will overflow some day. If a overflowed, it's still OK. But if b overflowed, it would be a false alarm. How to make this check bulletproof?
I know making a and b uint64_t would delay this false-alarm. but it still could not completely fix this issue.
===============
Let me clarify a little bit: the counters are used to tracking memory allocations, and this problem is found in dmalloc/chunk.c:
#if LOG_PNT_SEEN_COUNT
/*
* We divide by 2 here because realloc which returns the same
* pointer will seen_c += 2. However, it will never be more than
* twice the iteration value. We divide by two to not overflow
* iter_c * 2.
*/
if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {
dmalloc_errno = ERROR_SLOT_CORRUPT;
return 0;
}
#endif
I think you misinterpreted the comment in the code:
We divide by two to not overflow iter_c * 2.
No matter where the values are coming from, it is safe to write a/2 but it is not safe to write a*2. Whatever unsigned type you are using, you can always divide a number by two while multiplying may result in overflow.
If the condition would be written like this:
if (slot_p->sa_seen_c > _dmalloc_iter_c * 2) {
then roughly half of the input would cause a wrong condition. That being said, if you worry about counters overflowing, you could wrap them in a class:
class check {
unsigned a = 0;
unsigned b = 0;
bool odd = true;
void normalize() {
auto m = std::min(a,b);
a -= m;
b -= m;
}
public:
void incr_a(){
if (odd) ++a;
odd = !odd;
normalize();
}
void incr_b(){
++b;
normalize();
}
bool check() const { return a > b;}
}
Note that to avoid the overflow completely you have to take additional measures, but if a and b are increased more or less the same amount this might be fine already.
The posted code actually doesn’t seem to use counters that may wrap around.
What the comment in the code is saying is that it is safer to compare a/2 > b instead of a > 2*b because the latter could potentially overflow while the former cannot. This particularly true of the type of a is larger than the type of b.
Note overflows as they occur.
uint32_t a, b;
bool aof = false;
bool bof = false;
if (condition_to_increase_a()) {
a++;
aof = a == 0;
}
if (condition_to_increase_b()) {
b++;
bof = b == 0;
}
if (!bof && a/2 + aof*0x80000000 > b) {
perror("Error happened!");
return -1;
}
Each a, b interdependently have 232 + 1 different states reflecting value and conditional increment. Somehow, more than an uint32_t of information is needed. Could use uint64_t, variant code paths or an auxiliary variable like the bool here.
Normalize the values as soon as they wrap by forcing them both to wrap at the same time. Maintain the difference between the two when they wrap.
Try something like this;
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a or b is at the maximum value) {
if (a > b)
{
a = a-b; b = 0;
}
else
{
b = b-a; a = 0;
}
}
if (a/2 > b) {
perror("Error happened!");
return -1;
}
If even using 64 bits is not enough, then you need to code your own "var increase" method, instead of overload the ++ operator (which may mess your code if you are not careful).
The method would just reset var to '0' or other some meaningfull value.
If your intention is to ensure that action x happens no more than twice as often as action y, I would suggest doing something like:
uint32_t x_count = 0;
uint32_t scaled_y_count = 0;
void action_x(void)
{
if ((uint32_t)(scaled_y_count - x_count) > 0xFFFF0000u)
fault();
x_count++;
}
void action_y(void)
{
if ((uint32_t)(scaled_y_count - x_count) < 0xFFFF0000u)
scaled_y_count+=2;
}
In many cases, it may be desirable to reduce the constants in the comparison used when incrementing scaled_y_count so as to limit how many action_y operations can be "stored up". The above, however, should work precisely in cases where the operations remain anywhere close to balanced in a 2:1 ratio, even if the number of operations exceeds the range of uint32_t.

About the exclusiveness of the cases of an if block

I have a question about good coding practices. I understand the differences between doing an if-else if and multiple ifs (that is, when a condition is met in an if-else if, the rest of the checks are skipped). I've found a piece of code along these lines:
if (A == 5) {
do_something();
} else if (B == 7) {
do_something_else();
}
I understand that this code won't check B == 7 if A == 5. The code works, so that means that B is only 7, if A is not 5, but I think this is just waiting to break when the code changes. What I would do is:
if (A == 5) {
do_something();
return or continue or break;
}
if (B == 7) {
do_something_else();
return or continue or break;
}
My question is, when I have multiple exclusive cases that depend on different, exclusive variables, what's the best way to tackle the flow control? I have the impression that the first code (with else ifs) depends a lot on other pieces of code to work, and that changes in other areas might break it. The second one seems to be a bit clunky. A switch could be a third option, but I would need to create another structure to hold the case and the logic to assign its value, and I think that it would be a bit clunky and counter-intuitive.
You asked about "exclusive" cases, but the issue with the conditions A == 5 and B == 7 is that they are not exclusive; they are independent.
For full generality you may need to test and handle all four cases:
if(A == 5) {
if(B == 7) {
/* case 1 */
} else {
/* case 2 */
}
} else {
if(B == 7) {
/* case 3 */
} else {
/* case 4 */
}
}
This is the notorious "bushy" if/else block. It's notorious because it can almost immediately become nearly impossible for a reader to follow, especially if the cases are involved, or more levels are introduced. (I think most style guides will tell you never to use an if/else tree that's 3 or more levels deep. I'd certainly say that.)
I have occasionally used these two alternatives:
(1) Fully decouple the cases:
if(A == 5 && B == 7) {
/* case 1 */
} else if(A == 5 && B != 7) {
/* case 2 */
} else if(A != 5 && B == 7) {
/* case 3 */
} else if(A != 5 && B != 7) {
/* case 4 */
} else {
/* can't happen */
}
The point here is to make it maximally clear to a later reader exactly which conditions go with cases 1, 2, 3, and 4. For this reason, you might as well list the last, else if(A != 5 && B != 7) case explicitly (as I've shown), even though by that point it's basically an "else".
(2) Contrive a "two level" switch. I can't say this is a common technique; it has a whiff of being "too clever", but it's robust and readable, in its way:
#define PAIR(b1, b2) (((b1) << 8) | (b2))
switch(PAIR(A == 5), (B == 7)) {
case PAIR(TRUE, TRUE):
/* case 1 */
break;
case PAIR(TRUE, FALSE):
/* case 2 */
break;
case PAIR(FALSE, TRUE):
/* case 3 */
break;
case PAIR(FALSE, FALSE):
/* case 4 */
break;
}
I wouldn't recommend this when the conditions are A == 5 and B == 7, because when you're down in the switch, it's not obvious what "TRUE" and "FALSE" mean, but sometimes, this sort of thing can read cleanly. It's also cleanly amenable to 3 or more levels of nesting, unlike "bushy" if/else trees, which as I said are notoriously unreadable.
The most robust way of programming this,
while avoiding the assumption that either A==5 or B==7 is to consider all the four cases:
if ((A == 5) && (B == 7))
{
do_somethingAB();
/* or */
do_somethingA();
do_somethingB();
} else if (A == 5)
{
do_somethingA();
} else if (B == 7)
{
do_somethingB();
} else
{
do_somethingNeither();
/* or
do nothing */
}
As I think you know, the two pieces of code are not equivalent. (They're equivalent IF they both contain "return or continue or break", which makes the question more interesting, but that's a different answer.)
In general, which one you choose (or how you choose to rewrite it) has to depend on precisely what you want the program to do.
When you write
if (A == 5) {
do_something();
} else if (B == 7) {
do_something_else();
}
you're additionally saying you want to do_something_else only if A is not equal to 5. That might be just what you want, or it might be a bug. If you wanted to achieve the same effect without an else, it would have to look like this:
if (A == 5) {
do_something();
}
if (A != 5 && B == 7) {
do_something_else();
}
The second piece of code you wrote in your question, on the other hand, has the potential to execute both do_something and do_something_else.
In general, it's best (clearest and least confusing) if all the conditions in an if/else chain test variations on the same condition, not some unusual mixture involving, for example, both A and B.
You use an if/else block when the alternatives are truly and deliberately exclusive, and when you want to emphasize this fact. You might choose to use separate if blocks (not chained with else) when the alternatives are not exclusive, or when they're only coincidentally or accidentally exclusive. For example, I have deliberately written code like
if(A == 5) {
do_something();
}
if(A != 5) {
do_some_unrelated_thing();
}
I might do this when the two things have nothing to do with each other, meaning that in some future revision of the program's logic, they might be not be exclusive after all. Or, I might do this if do_something is not a single like, but is a long, elaborate block, at the end of which I'm concerned that the reader might not have remembered why we were or weren't doing something, and that on the other hand we might want to do something else. For similar reasons, I've occasionally written
if(A == 5) {
do_something();
}
if(A == 5) {
do_some_unrelated_thing();
}
in the case that, again, the two things to be done had nothing to do with each other, and the reasons for doing them might diverge.
[This is now my third answer. The fact that I keep misreading your question, and failing to grasp the essential point you're asking about, suggests that maybe I shouldn't be answering at all.]
I think the essential point you're asking about concerns the case where the cases are independent, but you get the effect of an else due to the fact that each clause contains a control-flow statement which "goes out": a break, or a continue, or a return, or something like that.
In this specific case, my preference today would be not to use the else. When we write
if(A == 5) {
do_something();
return or continue or break;
}
if(B == 7) {
do_something_else();
return or continue or break;
}
it's clear that the two conditions have nothing to do with each other, other than that they're both cases that do something to "finish" the subtask being done, and leave the block of code that's responsible for performing that subtask.
When we write the two cases separately (without an else), we make clear not only that they're independent, but that they could be reordered, or that another case could be introduced in between them, etc.
But then again, could they be reordered? How likely is it that both cases A == 5 and B == 7 will both be true? And in that case, how important is it that do_something be done, as opposed to do_something_else? If the two cases can't be reordered, if it would be wrong to test B first and maybe do do_something_else, I suppose the explicit else is preferable, to tie the two cases together and make even more clear the requirement that A be tested first.
Like any question of style, the arguments for and against this sort of thing end up being pretty subjective. You're not likely to find a single, overwhelmingly convincing answer one way or the other.
One way to handle this is to use a do { ... } while (0); technique.
Here is your original code:
if (A == 5) {
do_something();
} else if (B == 7) {
do_something_else();
}
Doing else if on the same line is [IMO] a bit of a hack because it hides the true indentation:
if (A == 5) {
do_something();
}
else
if (B == 7) {
do_something_else();
}
Using the aformentioned technique, which I've used quite a lot is:
do {
if (A == 5) {
do_something();
break;
}
if (B == 7) {
do_something_else();
break;
}
} while (0);
This becomes even more evident when we increase the number of levels in the if/else ladder:
if (A == 5) {
do_something();
} else if (B == 7) {
do_something_else();
} else if (C == 9) {
do_something_else_again();
} else if (D == 3) {
do_something_for_D();
}
Once again, this is indented to:
if (A == 5) {
do_something();
}
else
if (B == 7) {
do_something_else();
}
else
if (C == 9) {
do_something_else_again();
}
else
if (D == 3) {
do_something_for_D();
}
Using the do/while/0 block, we get something that is simpler/cleaner:
do {
if (A == 5) {
do_something();
break;
}
if (B == 7) {
do_something_else();
break;
}
if (C == 9) {
do_something_else_again();
break;
}
if (D == 3) {
do_something_for_D();
break;
}
} while (0);
Note: I've been programming in c for 35+ years, and I've yet to find a case where a more standard use of do/while (e.g. do { ... } while (<cond>)) can't be replaced more cleanly/effectively with either a standard for or while loop. Some languages don't even have a do/while loop. Thus, I consider the do loop to be available for reuse.
Another use of do/while/0 is to allow things defined by a preprocessor macro to appear as a single block:
#define ABORTME(msg_) \
do { \
printf(stderr,"ABORT: %s (at line %d)\n",msg_,__LINE__); \
dump_some_state_data(); \
exit(1); \
} while (0)
if (some_error_condition)
ABORTME("some_error_condition");

Arrangement of 2 by 2 condition in if statement in C-family language

When programming, I'm usually dealing with two sets of conditions combined together, like:
if (A && B){...}
else if (!A && B){...}
else if (A && !B){...}
else if (!A && !B){...}
It can also be resolved using nested if statements.
if (A){
if (B) {...}
else {...}
}
else {
if (B) {...}
else {...}
}
EDIT: Some new thoughts, what about I firstly evaluate both A and B and store as temporary variable (then do as the first approach) in case that the evaluation of A and B both have no side-effect?
So my question is there any performance difference between them and what about their readability?
I code in C++, if matters.
The two cases are not the same. In the second case, A and B will each be evaluated exactly once. In the first case, A and B will evaluated a number of times, depending upon their value.
While this almost certainly won't affect the optimization of the typical case, it will matter if A or B have side effects.
There's no way to predict which code generation strategy the compiler will choose in cases like that (and it can actually depend on surrounding context). This makes your question unanswerable in general case. One should normally expect the compiler to be smart enough to recognize the equivalence of both of your constructs (assuming they are indeed equivalent) and choose the most optimal one automatically.
The most optimal code generation strategy might be something else altogether, e.g.
// Assuming A and B are either 0 or 1
switch ((A * 2) + B) {
case 0: ...; break;
case 1: ...; break;
case 2: ...; break;
case 3: ...; break;
}
Just choose whatever makes your code more readable.
It's a hard question; honestly, I think everyone looks at this a little bit differently. As people have mentioned here it does not matter as a compiler should generate the same output for both (should! not necessarily will — it honestly depends on the code).
Yet, for example, let's look at this code:
int Nested(int a)
{
if(a > 0)
{
if( a > 1)
{
if( a % 2 == 0)
{
if( a % 10 == 4)
{
printf("a is valid");
return 1;
}
else
{
printf("a's last digit inst 4");
}
}
else
{
printf(" a is not odd");
}
}
else
{
printf(" a is not bigger than 1");
}
}
else
{
printf(" a is not bigger than 0");
}
return 0;
}
int NotNested(int a)
{
if(a <= 0)
{
printf(" a is not bigger than 0");
return 0;
}
if(a <= 1)
{
printf(" a is not bigger than 1");
return 0;
}
if(a % 2 != 0)
{
printf(" a is not odd");
return 0;
}
if( a % 10 != 4)
{
printf("a's last digit inst 4");
return 0;
}
printf("a is valid");
return 1;
}
I personally think that NotNested in my example is much more readable,
yet it's my personal opinion and both of these functions should do the same.
So yeah, in terms, of readability try to avoid nesting.

Is it possible to embed "for loop" inside an "if statement" to compare multiple condition before continuing using c++

In this program, the user must type in an 3 letter departing airport code (userFlight) and I will give them back the possible destinations. To check that what they typed in is one of the valid airport codes (departureAirport) I want to compare userFlight and make sure it is one of the possible departureAirports which I have stored in a vector called flights[]. This code obviously isn't working, but is there a similar way to accomplish this?
if
(for (j = 0, j < flights.size, j++)
{
(userFlight != flights[j].departAirport)
})
{return errorCode};
else
{//doSomething()};
If it has a operator< inside which does compare like your condition, how about
if(std::find(flights.begin(), flights.end(), userFlight) != flights.end())
{
/* found */
}
else
{
/* not found */
}
Else, if you don't like that, just check if the loop runs through all indices:
size_t i;
for (i = 0, i < flights.size, i++)
{
if(userFlight == flights[i].departAirport)
break;
}
if(i < flights.size)
{
/* found */
}
else
{
/* not found */
}
But no, a syntax like you want doesn't exist.
The code structure you were aiming for is:
for (j = 0; j < flights.size(); j++)
if (userFlight == flights[j].departAirport)
break;
if ( j == flights.size() ) // we got to the end
return errorCode;
doSomething(j);
However, this is a C-like code style. Not that there is anything wrong with that, but C++ allows for algorithms to be expressed more abstractly (and therefore, easier to read and maintain). IMHO it would be better to use one of the other suggestions such as std::set or std::find_if.
It sounds like you actually want to have a std::set of departing airports.
std::set<std::string> departing_airports = {"DTW", "MKE", "MSP", };
assert(departing_airports.count("DTW") == 1);
Yet another option is std::any_of. Assuming flights contains objects of type Flight:
if (std::any_of(std::begin(flights), std::end(flights),
[&](const Flight& f) { return userFlight == f.departAirport; }))
return errorCode;
doSomething();