Branching without if statement - if-statement

Is it possible to branch code without using an if statement?

Yes, you can, GPU-style.
Say you have a function that branches, and returns a value at the end.
float function( float input )
{
if( input > 0 )
{
// do stuff
finalValue = 2+4+8*input;
return finalValue ;
}
else
{
// do other stuff
finalValue = 1+input;
return finalValue ;
}
}
To do this without branching, you can write the code GPU-style: that is, evaluate both branches, then throw away the one you don't want at the end.
float function( float input )
{
// do stuff..regardless
finalValue1 = 2+4+8*input;
// do other stuff..regardless
finalValue2 = 1+input;
bool resultMask = input > 0 ; // 1 if should use finalValue1.
return finalValue1*resultMask + finalValue2*(1 - resultMask) ;
}
So there you have it. Branching without branching, if statements without if statementing.

Depends on what you mean by "branch" and "if". Any of the below branch, with no "if".
switch (foo) {
}
Or ternary operators, if you don't count:
x == 0 ? doFunc1() : doFunc2()
If your language supports function pointers:
funcArray[selectedOption]()
You can be silly and do:
boolean once = true;
while (condition && once) {
doAWhichNeverReturns();
once = false;
}
doB();
But I don't think this really answers your question, because I don't know what you're trying to do.

I was thinking about that because in mindastry game there is no dynamic if-statements, its simple script.
If you know adresses, you can use a max function:
0: set adressFalse = 5;
1: set adressTrue = 7;
2: set boolean // 0 or 1
3: adress = max (adressTrue * boolean, adressFalse) // 7 or 5
4: goto adress
5: print("false");
6: goto 8
7: print("true");
8: // next code
Pay attention: goto input isnt a expression here.

Related

Convert a boring list of switch statements to something shorter and pleasing to look at?

I have a switch statement that runs like this
switch (abc) {
case FILE_0:
lf = m_a->olf[0];
kf = m_a->pkf[0];
break;
case FILE_1:
lf = m_a->olf[1];
kf = m_a->pkf[1];
break;
.
.
default:
LOG_ERR << "Wrong type to check";
return 0;
}
This happens about 30 times and i end up with 30 cases in this single switch.
Any way to shorten it in C++ 11 ? E.g. using templates.
Your code ain't that big to be sure about the intent, though, from what I can see in the snippet, you actually want to convert the symbolic value into an index. (Can I assume this is an enum?)
What I would do is to move that code into a separate function:
auto fileEnumToIndex(FileEnum file) {
switch (file) {
case FILE_0: return 0;
case FILE_1: return 1;
default: __builtin_unreachable();
}
}
Your code than changes to:
auto index = fileEnumToIndex(abc);
lf = m_a->olf[index];
kf = m_a->pkf[index];
If the FileEnum is a real enum, you can change the code in the function fileEnumToIndex to a simple static_cast
To cover the default case, you could return a std::optional and use the std::nullopt case to do some error handling. However, when FileEnum is an actual enum, I would assume error handling when you determine that value.
You can create a map of abc and the indice and use that for determining the indice.
// somewhere, maybe outside functions
static const std::unordered_map<abc_type, int> table = {
{FILE_0, 0},
{FILE_1, 1},
...
};
// inside function
auto idx_itr = table.find(abc);
if (idx_itr != table.end()) {
lf = m_a->olf[*idx_itr];
kf = m_a->pkf[*idx_itr];
} else {
// default case
}

Index of the condition that was satisfied inside if-statement

if(command[i]=='H' or command[i]=='h' or command[i]=='C' or command[i]=='c'){
do something;
}
Once the logic flow goes inside this if-statement, I want to know what exactly command[i] was. Surely I can make individual comparisons again in the inside block and find out, but is there a more elegant way of knowing, say, the index of the condition that was satisfied?
If you use
if((myC=command[i]) =='H' ||
(myC=command[i]) =='h' ||
(myC=command[i]) =='C' ||
(myC=command[i]) =='c')
then the value of the successful expression will end up in myC, because evaluation in a chain of "or"s stops at the first true subexpression.
If you go one step further you can get a number value identifying the subexpression by index.
if(((myC=1), command[i]) =='H' ||
((myC=2), command[i]) =='h' ||
((myC=3), command[i]) =='C' ||
((myC=4), command[i]) =='c')
Same concept, the first successful subexpüression is the last to be evaluated and the , operator ensures that only the second part gets used for the comparison.
Another option is to assign a value. You could use switch, an if..else tower, or a function with return statements. Here is a version with function:
int classify( char command )
{
switch( command )
{
case 'H': return 1;
case 'h': return 2;
case 'C': return 3;
case 'c': return 4;
default : return 0;
}
}
void func(void)
{
int result = classify( command[i] );
if ( result )
{
// use result value here as appropriate
}
}
It would also be possible, in fact preferable, to use an enumerator instead of magic numbers.
Just do this -
if(command[i]=='H' or command[i]=='h' or command[i]=='C' or command[i]=='c'){
print command[i]; //use whatever command is appropriate for printing
do something;
}

Need help making my switch case look nicer

So basically my switch case works but my professor says there are too many returns and "use a variable result, then return it at the end!"
so here is my code
int getMonthValue(){
switch(month){
case(1): //January
if(isLeapYear(year) == true)
return 6;
else
return 0;
case(2): // February
if(isLeapYear(year) == true)
return 2;
else
return 3;
case(3): //March
return 3;
case(4): //April
return 6;
case(5): //May
return 1;
case(6): //June
return 4;
case(7): //July
return 6;
case(8): //August
return 2;
case(9): //September
return 5;
case(10): //October
return 0;
case(11): //November
return 3;
case(12): //December
return 5;}
};
I dont see anything wrong with it, I am sure it could be written better. Would someone be able to show me a way to either format this in a more user friendly way? My professor also wanted me to use breaks in the switch instead, not sure why to use the break over return.
This is not good idea to use logical operators in your case. Use a array! This code is very well understood and it is very fast. And it is very easy to change the return value:
unsigned getMonthValue(unsigned month, unsigned year) {
const static unsigned ans[2][12] = {
// Jan F M A M J J A S O N Dec
{0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 } //normal year
, {6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 } //leap year
};
assert(month <= 12);
assert(month >= 1);
const size_t month_index = month - 1;
const size_t leap = isLeapYear(year) ? 1 : 0;
return ans[leap][month_index];
}
UPDATE
There is very useful link about this technic - Lookup_table. Thanks to Schwern!
Try this
int getMonthValue(int month, int year){
map<int,int> staticAnswers;
staticAnswers[3] = 3;
staticAnswers[4] = 6;
staticAnswers[5] = 1;
staticAnswers[6] = 4;
staticAnswers[7] = 6;
staticAnswers[8] = 2;
staticAnswers[9] = 5;
staticAnswers[10] = 0;
staticAnswers[11] = 3;
staticAnswers[12] = 5;
switch(month){
case(1): //January
if(isLeapYear(year) == true)
return 6;
else
return 0;
case(2): // February
if(isLeapYear(year) == true)
return 2;
else
return 3;
default:
return staticAnswers[month];
};
Here is how I would write it:
int
getMonthValue (int month, int year)
{
switch(month)
{
case 1: // January
if (isLeapYear(year))
return 6; // explanation here of why 6 is the right value
return 0;
case 2: // February
if (isLeapYear(year))
return 2; // explain why 2 is the right value
return 3;
case 3: return 3; // March
case 4: return 6; // April
case 5: return 1; // May
case 6: return 4; // June
case 7: return 6; // July
case 8: return 2; // August
case 9: return 5; // September
case 10: return 0; // October
case 11: return 3; // November
case 12: return 5; // December
}
}
I know many inexperienced programmers would object to the statements not being consistent. However—written this way—the statement structure exactly follows the logic. That is, the lexical structure reveals the logic.
A good thing about switch statement is that you are allowed to fall-through case statements, so this is allowed in C++:
switch (month) {
case 4:
case 7:
return 6;
case 9:
case 12:
return 5;
Which should reduce the amount of return statements but will change the readable order.
Another option, since you are checking for all values in range [1-12], would be to use an array, eg:
static const int values[] = { 3, 6, 1 ... };
if (month < 3) {
/* leap year check */
}
else
return values[month - 3]; // we subtract 3 to start from March
But this in the end should be mostly personal preference, so the suggestion given by the professor sounds like just something to nag you.
Your professor is strictly enforcing the "Single Entry, Single Exit" (SESE) rule of Structured Programming. All inputs come in as arguments. All output is via a single return statement at the end. No surprise returns in the middle of the routine. No globals. Minimal side effects. No gotos. It makes code easier to read when you don't have to carefully scan it for returns or calling gotos in the middle of a function.
This is a good rule of thumb. And at the time this was conceived, in the 1970s, this was a radical idea. Now it's just how you do things.
The problem, like many style rules, is when you strictly enforce the rule without considering why the rule exists; you can wind up with the opposite effect. Some of the answers here have illustrated that nicely. Style rules are necessarily simplified versions of reality and enumerating all the edge cases and exceptions is difficult. Gotta allow some wiggle room.
For a small routine like yours that does one very clear thing, fits on one page, and is one easy to read switch statement... just do multiple returns like you're doing. Storing a return value for the end would make it longer and more complicated defeating the point of the rule. And you avoid forgetting a break, a very common C pitfall.
The other good reason to violate SESE is early exit. Structured programming says to do this:
int some_function(int arg) {
int ret;
if( arg < 0 ) {
ret = arg;
}
else {
this is the real
meat and potatoes
of the function
and because of
that one simple
condition at the
top it all
is indented an
extra level
adding complexity
to the whole
function
ret = whatever;
}
return ret;
}
Every level of nesting adds complexity. Early exit avoids this unnecessary nesting by getting the simple cases out of the way at the top.
int some_function(int arg) {
if( arg < 0 ) {
return arg;
}
this is the real
meat and potatoes
of the function
which doesn't
have to be indented
an extra level
since we dealt with
all the simple cases
at the top
return whatever;
}
The extra return at the start doesn't significantly add complexity because it's in a predictable spot. It's only surprise returns in the middle of a large function that are a problem.
The other side of this is minuscule style arguments like this can distract from real problems. Your code has two much bigger problems, and I hope your prof called you on them.
Pass values into functions, don't use globals.
Your function takes no arguments. Instead month and year are globals. This is very bad style. It makes your program difficult to understand because anything can potentially effect anything. Instead, pass them in.
int getMonthValue( int month, int year ) {
...
}
Check your bounds.
The second problem is your function has no bounds checking. What if month is 0? 13? -50? 20398? It will fall through the switch statement and out the bottom of the function. The compiler should have warned you about this.
test.c:48:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
To solve this, unless you can think of a good reason not to, always put a default clause on switch.
switch(month) {
...all your regular cases...
default:
fprintf(stderr, "Month %d is out of range.\n", month);
exit(1);
}
Your professor is right, don't worry its all in the learning process
Try something like this:
int result = -1;
switch(month){
case 1: //January
if(isLeapYear(year) == true)
result = 6;
else
result = 0;
break;
case 2: // February
if(isLeapYear(year) == true)
result = 2;
else
result = 3;
break;
case 3: //March
result = 3;
break;
case 4: //April
result = 6;
break;
case 5: //May
result = 1;
break;
case 6: //June
result = 4;
break;
case 7: //July
result = 6;
break;
case 8 : //August
result = 2;
break;
case 9: //September
result = 5;
break;
case 10: //October
result = 0;
break;
case 11: //November
result = 3;
break;
case 12: //December
result = 5;
break;
}
return result;
Also don't use brackets in your cases it doesnt look clean at all.
I sometimes also choose to use brackets in my cases "{" and "}" although in this example its probably more appropiate not to. Weather or not using brackets is the best practice I do not know.
I am refeering to these brackets by the way "{" and "}"
Anyway thats a cleaner case statement, hope it helped.
a possible solution With the ternary operator!:
int getMonthValue()
{
return
month == 3 ? 3 :
month == 4 ? 6 :
month == 5 ? 1 :
month == 6 ? 4 :
month == 7 ? 6 :
month == 8 ? 2 :
month == 9 ? 5 :
month == 10 ? 0 :
month == 11 ? 3 :
month == 12 ? 5 :
month == 1 ? isLeapYear(year) ? 6 : 0 :
month == 2 && isLeapYear(year) ? 2 : 3 ;
}

C++ if statement notation - Is this equivalent?

I'm 99% sure this won't work but that remaining 1% is bothering me
int x;
//is this if statement
if(x == 1, 5, 7)
{
//do something here
}
//equivalent to this if statement
if((x == 1) || (x == 5) || (x == 7))
{
//do something here
}
No it's totally not equivalent.
if(x == 1, 5, 7)
calls the comma operator, which will effectively end up in the last value because of , has the lowest precedence:
if(7)
since unfolding with parenthesis should look like
if(((x == 1), 5), 7)
while
if((x == 1) || (x == 2) || (x == 7))
checks if x equals either 1, 2 or 7.
They are not equal. When you write it like
if(x == 1, 5, 7)
{
//do something here
}
it basically translates into
if(7)
{
//do something here
}
which will always be true in case the number in the condition block is a non-zero number.
Example 1:
int main()
{
int x=10;
if(x==1,5,7)
cout<<"hello"<<endl;
return 0;
}
Here, the output is "hello", because 7 is treated as a true boolean variable.
Example 2:
int main()
{
int x=10;
if(x==1,5,0)
cout<<"hello"<<endl;
return 0;
}
Here, there is no output because 0 is considered as a false boolean variable.
Regarding a faster solution discussed in the comment section of the OP, here's a 'fast' solution:
If you have a large number of constant comparisons to perform, a switch statement is faster than individual if(x == 1) statements as it is compiled to a branch-table (a kind of hashtable directly within program code, giving it O(1) lookup), however it's possible that existing compilers will already optimize if(x==1||x==2||x==3...) to a branch-table too.
bool xIsInSet = false;
switch( x ) {
case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7: // add a case for each literal comparison
xIsInSet = true; // no `break` needed, there's only 1 case.
}
if( xIsInSet ) {
// do stuff
}
This can be inlined to a lambda which is invoked immediately to eliminate xIsInSet:
if( [&x]() -> bool {
switch(x) { case 0: case 1: case 2: case 3: return true; }
return false; }()
) {
// do stuff
}
Unfortunately C++11's variadic templates don't let us dynamically add case statements, and hacking it using a preprocessor #define is possible - if you don't mind using a metaprogramming library. A better alternative might be an inline #include of a file generated by your build script. What would be even neater would be a way to somehow #include the standard-output from another program (e.g. if we could do #include '.\generateCasesFor.sh 1 2 5 10 12', alas not yet).

Multiple Statements for question mark operator

I have two variables
int a, b ;
a and b can have any of the values from 0-3 and there should be a couple of sentences for each condition based on values of a and b.
I used nested switches:
switch(a)
{
case go:
{
switch(b)
{
case go: {...}
...
case write: {...}
}
}
...
case 3:
{
...
}
}
Also I have an
enum
{
go = 0 ;
wait =1 ;
read = 2;
write =3 ;
}
I have a very big nested switch to check all the 4*4 =16 conditions
I would like to implement using question mark ? : operator
something like
(a=b==0) ? Do something ? Do something.
However I have multiple statements to do in each condition.
How do I do this using this ? : ternary operator?
Thanks in advance
You might instead want to consider flattening your 4 x 4 switch blocks into a single 16 way switch:
#define SELECT(a, b) ((a) * 4 + (b))
int select = SELECT(a, b);
assert(a >= 0 && a < 4); // sanity checking - make sure a and b are valid
assert(b >= 0 && b < 4);
switch (select)
{
case SELECT(0, 0):
// ...
break;
case SELECT(0, 1):
// ...
break;
case SELECT(0, 2):
// ...
break;
case SELECT(0, 3):
// ...
break;
case SELECT(1, 0):
// ...
break;
// ...
case SELECT(3, 3):
// ...
break;
}
Note that this works OK in both C and C++. It also works regardless of whether a and b are ints or enums (note that you can use actual enum labels in the SELECT macro - you don't need to use literal constants).