C++: Is there anyway to know what triggered an If-Statement? - c++

Suppose I have an if-statement like this:
if ( x < 0 || y < 0 || z < 0) {
cout << "Something is less than zero!";
}
Is there anyway to know which disjunct in the disjunction triggered the if-statement? Or is it necessary to write three separate if-statements to achieve that end?
EDIT: The goal would be to short-circuit the process. Obviously, writing any more code than three separate if-then statements (for this case) would not work for this goal.

Speaking of convoluted methods that would be stupid:
convoluted_and_stupid( x < 0, y < 0, z < 0 );
void convoluted_and_stupid( bool xlz, bool ylz, bool zyz )
{
if( xlz || ylz || zlz )
cout << "something is less than zero!\n";
if( xlz )
cout << "it is x!\n";
if( ylz )
cout << "it is y!\n";
if( zlz )
cout << "it is z!\n";
}

Just with that context the answer is no, you cannot really tell which of the three variables is < 0 without adding extra nested ifs for each of the variables. All you know is that at least one of them (but maybe more than one) is.

Related

Why does results are different when relational operators means the same?

For clarification, let's consider the following program:
#include <iostream>
int main(void) {
short int i; // declaration
short int value;
short int sum;
i = value = sum = 0; // initialization
std::cout << "Enter a value: ";
std::cin >> value;
while (i != value) { // ### here's the confusion ###
sum += i;
i++;
}
std::cout << "Total sum: " << sum << std::endl;
return 0;
}
Look at the while (i != value), when this expression is given, the results shows Total sum: 45 whereas if we put while (i <= value), it shows Total sum: 55. (Input's given 10 for example)
Here, the confusion is, when should we use != and <= or >= operations in loops, any specific condition?
According to TutorialsPoint's Operators Reference
it tells that != (returns true used when two operands are unequal).
<= (returns true when used when we need to ensure if the first operand is lesser than or equal to second).
It was expected to get no difference in output, but something's misunderstood.
This while loop
while (i != value)
does not include the iteration when i is equal to value because in this case the condition i != value evaluates to false.
This while loop
while (i <= value)
includes the iteration when i is equal to value because in this case the condition i <= value evaluates to true.
In fact the first condition can be rewritten the following way (provided that initially i is less than value)
while ( i < value )
Now compare it with the condition in the second loop that in turn can be rewritten like
while ( i < value || i == value )
That is you have two different conditions.
With
while( i <= value)
the last iteration is with i == value. With
while ( i != value)
The body of the loop will not be executed when i == value. That is the reason you observe the difference.
This is a good chance to learn how to use a debugger. And/Or realize that your example is already too complicated to directly see what is going on. You would have spotted the difference more easily with
int i = 0;
int value = 5;
while ( i != value) {
std::cout << i << " ";
}
i = 0;
while ( i <= value) {
std::cout << i << " ";
}

How to programmatically see which conditions were not met in C++ when using logical AND (&&)?

I am trying to efficiently deduct which conditions caused an if statement to be overlooked by the program without using a sequence of if statements to verify each variable's relative integrity individually.
Is this possible?
bool state = false;
int x = 0;
int y = 1;
int z = 3;
if(x == 0 && y == 1 && z == 2) {
// Do something...
state == true;
}
if(state == false) {
std::cout << "I did not execute the if statement because the following
conditions were not met: " << std::endl;
/*Find a way to make the program output that z != 3 stopped the
conditional from running without directly using if(z != 2)*/
}
You could introduce a counter as a "condition" between each of the conditions in the if to see when short-circuit evaluation of operator && prohibits execution of the latter conditions:
int nrOfConditionFailing = 1;
if(x == 0 &&
nrOfConditionFailing++ && y == 1 &&
nrOfConditionFailing++ && z == 2) {
state = true;
}
if (!state) {
cout << "failed due to condition nr " << nrOfConditionFailing << endl;
}
If you want to check all the conditions, you cannot do it in a single if-statement; Short-circuit evaluation of operator && will prevent the latter conditions to be even checked/evaluated if one of the former conditions evaluates to false.
However, you could do such a check as an expression that marks a bit in an unsigned int for each condition that is not met:
int x = 1;
int y = 1;
int z = 3;
unsigned int c1 = !(x == 0);
unsigned int c2 = !(y == 1);
unsigned int c3 = !(z == 2);
unsigned int failures =
(c1 << 0)
| (c2 << 1)
| (c3 << 2);
if (failures) {
for(int i=0; i<3; i++) {
if (failures & (1 << i)) {
cout << "condition " << (i+1) << " failed." << endl;
}
}
}
else {
cout << "no failures." << endl;
}
If this is something you want to display to the end user, and not just while debugging, as suggested in the comments, you can design a simple data structure for yourself. It would be a list / vector / array of entries, each of which contain a) a value to compare against, b) a value to test, and optionally c) a description of the test.
Then simply iterate the list, and check if equality holds for all of them. If not, you can stop the flow of the programme and print out the description.
To more directly answer your question: no, there is nothing in C++ that would allow you to examine the results of previous statements. The statements and operations you see in the source code get compiled and possibly won't even be trivially recognisable among the assembly instructions. Being able to check the results would mean the data has to be stored somewhere, which would be an incredible waste of memory and processing time. That is why you have to do this yourself.
Is this possible?
It is not possible in the way you were thinking about the problem. You can solve your problem instead by running each test individually, storing the result, and then identifying which of them were false:
std::vector<std::tuple<std::string,bool> > tests = {
{"x==0",x==0}, // test name as a string followed by the actual test
{"y==1",y==1},
{"z==2",z==2}
};
if(!all_of(tests.begin(),tests.end(),[](std::tuple<std::string,bool> &t) { return std::get<1>(t); }))
{
std::cout << "The following tests failed: ";
//remove all tests that passed
tests.erase(
std::remove_if(tests.begin(),tests.end(),[](std::tuple<std::string,bool> &t) { return std::get<1>(t); }),
tests.end());
//This will only print out the tests that failed
std::transform(tests.begin(),tests.end(),std::ostream_iterator<std::string>(std::cout, " "),[](std::tuple<std::string,bool> &t) { return std::get<0>(t); });
std::cout << std::endl;
} else {
//what to do if all tests were true
}
This will evaluate all tests (i.e., it won't use &&'s short-circuiting) and print all the ones that failed. You could likely wrap this into a class to make this more generalizable and user friendly.
The original code tests each variable individually. The && series is exactly equivalent to a series of if...else statements. There's nothing inefficient about one compared to the other, and there's nothing "clever" about using some tricky solution that achieves the same end result as straightforward code.
I might write:
char const *reason = nullptr;
if(x != 0)
reason = "x failed";
else if (y != 1)
reason = "y failed";
else if (z != 2 )
reason = "z failed";
if ( reason )
std::cout << reason << '\n';
else
{
// success code here...
}
I would typically do something like the following to determine if a series of validity checks worked and to mark which ones failed.
unsigned long ulFlags = 0;
int x = 0;
int y = 1;
int z = 3;
ulFlags |= (x == 0) : 0 ? 0x0001; // if bit set then condition failed.
ulFlags |= (y == 1) : 0 ? 0x0002; // if bit set then condition failed.
ulFlags |= (z == 2) : 0 ? 0x0004; // if bit set then condition failed.
if(ulFlags == 0) {
// Do something since all conditions are met and valid ...
} else {
std::cout << "I did not execute if statement because: " << std::hex << ulFlags << std::endl;
/* Find a way to make the program output that z != 3 stopped the
conditional from running without directly using if(z != 2) */
}
This is the same idea as some of the other answers, but with a template to simplify the syntax to use it. Stores all the individual checks in an std::array<bool, N> and one additional bool to be able to re-check the full statement without going through the individual results again.
No dynamic allocation is a plus as well.
#include <iostream>
#include <array>
#include <type_traits>
template <typename... N>
struct what_failed {
what_failed(N... n) : arr{n...}, status{(... && n)} {
static_assert(std::conjunction_v<std::is_same<N, bool>...>, "Only pass bools");
}
std::array<bool, sizeof...(N)> arr;
bool status;
operator bool() { return status; }
};
int main() {
auto check = what_failed(2 == 5, 2 < 5, 2 > 5, 1 == 1);
if (check)
std::cout << "Check: All true";
else {
std::cout << "Check: ";
for (auto c : check.arr)
std::cout << c << ' ';
}
return 0;
}
This requires c++17 due to fold expressions and template deduction in a constructor, but that can be worked around for c++11 with a couple of extra help-templates.

c++ nested conditional operator loop

I'm curious about how c++ handles this nested conditional operator. I'm half sure that I understand how this works, but I'm curious, could anyone explain through a diagram how the loop would execute the nested conditional operator.
For example would the loop execute through the first expression of each conditional operator for each instance?
Also is this nested conditional operator structured as:
(i < 2) ? x[i] : y;
!i ? y : x[1];
I guess I'm just very curious about the nature of this. Please don't answer unless you are capable of giving me a thorough adequate explanation of how the loop executes this conditional operator.
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
const char x[2] [20] = {" Cloud "," at your service\n"};
const char * y = "Strife";
for (int i = 0; i < 7; i++)
cout << (( i < 2)? !i ? x [i] : y : x[1]);
cout << endl << endl << x[0] << endl << x[1] << endl;
cin.get();
cin.get();
return 0;
}
It seems you are asking how an expression like x ? y ? 1 : 2 : 3 is parsed.
If you think about it there is really only one possibility. Namely, the : furthest to the right must bind to the ? furthest to the left. Thus the expression parses as:
x ? (y ? 1 : 2) : 3
So, if x and y are true, then 1 is returned; if x but not y is true, then 2 is returned; and if x is false, then 3 is returned.
Sorry to not answer directly in the context of your problem but I felt like it would be easier to follow this way.
When in doubt, spell it out...
for (int i = 0; i < 7; i++)
{
if (i < 2) {
if (!i) { // technically, this is "if i == 1"
cout << x[i];
} else { // and this is "if i == 0"
cout <<y;
}
} else {
cout << x[1];
}
}
Simply go through the statement. Everything before a ? goes in an if, then just open a { until we see a :.
The operator is not structured as you write. Maybe it is clearer with parentheses:
cout << ((i < 2) ? (!i ? x [i] : y) : x[1]);
Some good analysis already of what the conditional means. Just wanted to contribute a couple suggestions:
consider writing or reordering such expressions such that the ? and : alternate,
consider breaking them on to multiple lines with indentation reflecting their processing.
Either or both of these should make it easier to keep track of what they do.
Consider:
i < 2 ? !i ? x[i] : y : x[1] # somewhat confusing...
Just indenting to reveal processing precedence:
i < 2 // if just put ? and : beneath related condition
? !i // then if
? x[i] // then
: y // else
: x[1] // else
Or to simplify while keeping one-liner concision, try:
i >= 2 ? x[1] : !i ? x[i] : y # equivalent but simpler to "grok" (see below)
Expression ordered to alternate ? and : work like a simple if / else if / else if / else chain, so you can process and eliminate possibilities steadily as you work your way through.
if (i >= 2)
(value is) x[1]
else if (!i)
x[i]
else
y;
I sometimes write alternating conditionals across lines too:
std::cout << (i >= 2 ? x[1] : // "if condition1 then value1 else
!i ? x[i] : // if condition2 then value2 else
y); // value3"
...or sometimes (depending on the line lengths and visual complexity) going the whole hog and lining up the : beneath ?...
std::cout << (i >= 2
? x[1]
: !i
? x[i]
: y);
As with many stylistic aspects of C++ source code, picking a nice layout is a bit of an art - but experimentation is a good way to get a feel for it.

Matching nulls(0) in int [c++]

I have a problem with checking on 0, i trying to get numbers from file(and i get it) but if is 0 then said me >
0 maybe its not found!(0 | 0)
0 maybe its not found!(1 | 1)
0 maybe its not found!(2 | 2)
0 maybe its not found!(3 | 3)
0 maybe its not found!(4 | 4)
if i want 1 and i gets the correct line from line:
0 maybe its not found!(0 | 0)
[Line0]: 1 1 1 200 150 6 1 10000000 1
[Line1]: 1 1 13 14
0 maybe its not found!(2 | 2)
0 maybe its not found!(3 | 3)
0 maybe its not found!(4 | 4)
Check func is :
int myClass = 0; //'\0'
for(int i=0; i < Show.line0 && Show.line1; i++)
{
if( Show.Get[i].m_Class0 && Show.Get[i].m_Class1 == myClass )
{
........
}
else
{
cout << myClass; cout << " maybe its not found!";
cout << "(";
cout << Show.Get[i].m_Class0;
cout << " | ";
cout << Show.Get[i].m_Class1;
cout << ")";
cout << endl;
}
m_class0/1 are int and the value its getted from the loaded file.
in other value on myClass bigger then 0 i gets the same line lines from file begining with wanted number, but doesnt works with 0.
Your error lies in the following line:
if( Show.Get[i].m_Class0 && Show.Get[i].m_Class1 == myClass )
Here, the compiler evaluates:
Show.Get[i].m_class0
If this is true, the compiler goes on to evaluate:
Show.Get[i].m_Class1 == myClass
If this is true (the other one must be true at this point, unless && was overloaded), then the if block executes.
The problem lies within the first condition. It will be true when Show.Get[i].m_Class0 does not equal 0.
What you really want is the opposite in this case (since myClass is 0):
if( Show.Get[i].m_Class0 == myClass && Show.Get[i].m_Class1 == myClass )
Now I mentioned a couple of things in there. The first is that the second part will only be evaluated if the first is true. This is called short circuit evaluation, and is used to save time. However, if one were to overload operator&&, the short circuit no longer kicks in. That is the second, and this is why it's generally a bad idea to do so, as it can give unexpected side effects from the second condition.
For example:
if (false && ++x)
would leave x if the && is native, but increment x if it is an overloaded version.
if( Show.Get[i].m_Class0 && Show.Get[i].m_Class1 == myClass )
As #chris commented, this is not doing what you seem to think.
if (A && B == 0) does not mean "if A and B are both equal to zero"
It means "if A is true, and B is equal to zero" and that fails when A is zero, because zero is false
You want if (A == 0 && B == 0) which means "if A is equal to zero and B is equal to zero"

Multiple if statements in C++

I'm doing the first project euler problem and I just did this
#include <iostream>
using namespace std;
int main(){
int threes =0;
int fives = 0;
int both = 0;
for (int i = 0; i < 10; i++){
if(i%3==0){
threes += i;
}
if(i%5==0){
fives += i;
}
if ( i % 5 == 0 && i % 3 == 0){
both += i;
}
}
cout << "threes = " << threes << endl;
cout << "fives = " << fives << endl;
cout << "both = " << both << endl;
cout << " threes + fives - both = " << endl;
int result = (threes + fives) - both;
cout << result<< endl;
return 0;
}
My professor recently corrected me for doing this in a different problem saying something about else statements,
but I don't understand WHY i have to add else in front of the next if. for what its worth I have another version with else if(i%5){ fives += .... }
and they both work and get me the right answer.
My question is whats inherently wrong with this way of thinking, is it stylistic or am I not thinking logically about something?
If it works, why use switch statements ever?
The only thing that I see wrong with your implementation is that in the case where the number is both a multiple of 3 and a multiple of 5 not only is the both variable incremented but the fives and threes variables are also incremented. Based on what the professor described I believe he wants you to use an else-if so that the both variable is the only one that is incremented when you pass in a number that is both a multiple of 3 and a multiple of 5.
The reason you get the correct answer both ways is because you are only going to 10 in the for loop, if you increase it to i <= 15 you will get fives and threes being 1 higher than I think he intended.
For example:
for( int i = 0; i < 10; i++ )
{
if( ( ( i % 3 ) == 0 ) && ( ( i % 5 ) == 0 ) )
{
both++;
}
else if( ( i % 3 ) == 0 )
{
threes++;
}
else if( ( i % 5 ) == 0 )
{
fives++;
}
}
The else branch in an if-else statement is only executed if the if branch is false. If you just have two if statements in a row, they'll both be executed, which can be a waste. In the below code, the else prevents the second computation from running if the first is satisfied.
if (expensive_computation1()) {
...
}
else if (expensive_computation2()) {
...
}
Additionally, it's clearer to humans reading the code whether both if statements should be allowed to run or whether only one should.
In this case, maybe you really want this:
if (i % 5 == 0 && i % 3 == 0) {
both += i;
} else if (i % 3 == 0) {
threes += i;
} else if (i % 5 == 0) {
fives += i;
}
(why you do += i instead of ++ I don't know but you didn't explain, so I just copied it)
In your code, threes and fives were incremented even if it would also increase both, which depending on your problem may not be what you want. If you do the if/else way I've just presented, only one of the three variables is increased.
Why use if-else instead of multiple if's?
if-else & if would achieve the same results but if-else achieves them in a performance enhanced way. with multiple if's every if condition will have to be checked. With if-else only one conditional check will have to be performed and the rest of the conditions just don't need to be checked at all.
This would not affect a small program like the one you have but it will sure have some impact in potentially expensive function being called repeatedly over and over again.
If it works, why use switch statements ever?
With nested if-else conditions the code is hard to read and understand. The switch-case construct helps to represent the conditions in a much easier to read & understand format.
To me it looks like stylistics. You can use some autoreformating tool that follows certain established stylistic look (K&R, ANSI, GNU, etc.)
For example astyle is such tool, http://astyle.sourceforge.net/ - just reformat your code with it, and you might have a happy professor.