Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I would like to know the correct usage of conditionals such as if statements to avoid undefined behaviours. Let's start with an example:
uint8_t x = 0;
bool y = false;
bool z = false;
if ((x == 135) and !y and !z) {
//do something
}
else if ((x == 135) and y) {
x = 5;
z = true;
}
else if ((x == 5) and z) {
x = 135;
z = false;
}
else {
//do something
}
Now, will I get undefined behaviour by not including all 3 variables into every condition? Will every unaccounted for condition go into the else statement? If so, what happens if I get rid of the else statement? I have the exact same if statement (in a more complex scenario) and I seem not to be getting into the right statements every time.
Please enlighten me if there is a rule for this?
will I get undefined behaviour by not including all 3 variables into every condition?
The behaviour of not including all variables into every condition is not undefined by itself.
Will every unaccounted for condition go into the else statement?
Statement-false (i.e. the statement after the keyword else) is executed if the condition is false.
what happens if I get rid of the else statement?
The execution continues from the statement after the if statement.
As a rule of thumb yes, it's a bad idea to attempt to read a variable that has not been initialised as quite often the behaviour on doing that is undefined. But that's not the case here: all your variables are initialised.
But all you need in an if(...) condition is something that evaluates to either true or false. On that point your code is absolutely fine. I'd use && and || rather than and and or though as the former are more common.
For a pretty comprehensive set of constructs that are undefined, see What are all the common undefined behaviours that a C++ programmer should know about?
No, you don't have undefined behaviour here. What it sounds like is that you don't have an accurate mental model of conditional (boolean) logic. else is always an optional part of an if statement.
Exactly one of the { ... } blocks will be executed. Changing the values of x, y or z inside any of them will not cause any others to be executed, the decision is made first.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Can any one explain this statement
int x=1,y=11,z;
z=x--&&y++¦¦--x;
I know the answer but not able to think that how it is coming
It pretty simple
x--
returns 1 (true). Therefore
y++
is evaluated. It returns 11
1 && 11
returns true. Since
true || X
is always true
--x
is not evaluated. The statement returns true (1).
This is called short-circuit evaluation. E.g.
a && b || c
means
if a is true
evaluate b
if a && b is false
evaluate c
You could rewrite it as
int x=1,y=11,z;
z=[&]() {
if (!(x--)) {
return false;
}
if (y++) {
return true;
}
if (x++) {
return true;
}
return false;
}();
It's important to notice that the order of evaluation is as described. That's one of the reasons you shouldn't overload operator&& or operator||. The described behavior only works if the operators are not overloaded.
This question already has answers here:
c++ styleguide: why to have non-lvalues on the left side?
(2 answers)
Closed 4 years ago.
Is there any difference between the following two code snippets?
if(x==4)
{
}
and
if(4 == x)
{
}
If so is there any great impact in performance?
Can there be a difference? Yes; if one of the types involved in the comparison is user-defined, then the writer of that type can make their operator== overload not be commutative.
However, such code should be considered ill-behaved. Users expect equality testing to be commutative. And in C++20, it will be much easier to write a commutative equality test than a non-commutative one.
So while the compiler will not stop you, it is reasonably safe to assume that equality testing will be commutative.
In the most common case (read: "should you not be using an overloaded operator == of yours that would make it different, and should the type of x be comparable to 4") these two snippets have similar performances: both terms are going to be evaluated and then compared.
However there are differences, at least in the approach. For example, should you write by accident:
int x = 2;
if(x = 4) // = instead of ==, typed by mistake
{
stuff();
}
this will compile (you might have warnings, but no error), and at run time, this will put 4 into x at test time. As x won't be equal to zero, the content of the block will be executed: stuff() will be called. So there will be a bug as your intent was not to change x and not to have the content of the block executed.
But if you write this:
int x = 2;
if(4 = x) // = instead of ==, typed by mistake
{
stuff();
}
this code will not compile as 4 is a rvalue that cannot be used at the left part of such an assignment.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Consider the speed of the following examples (please ignore that this example is completely ridiculous):
int multiply(int a, int b) {
if (a == 0 || b == 0) {
return 0;
}
if (a == b) {
return pow(a, 2);
}
return a*b;
}
versus
int multiply(int a, int b) {
if (a == 0 || b == 0) {
return 0;
} else if (a == b) {
return pow(a, 2);
} else {
return a*b;
}
}
Obviously, it's not really necessary here, but when I'm working with complex operations, I find it a lot easier to read when formatted as the latter. Does it take any longer to run in the second configuration? Will I be sacrificing anything?
EDIT: Answering's OP question first, then talking about the general case.
Sepcific-to-your-problem Answer: In your case, since you have the return, under each condition, it will break out of the flow-control. In a general case, chaining them, when necessary, is better.
General Answer: Yes, essentially when you're only using if, your program is checking all the conditions, even if one of them was met.
When doing a chain of if,else-if,else, once one of the conditions is met, all the others, in that chain, will be ignored.
In this particular case, no compiler I'm aware of would fail to
generate the exact same output for both. However, in the general
case:
Write for readability and maintainability
Profile profile profile
Optimize only where you find bottlenecks
Test your optimization using more profiling
The fourth part is important, hardware have many surprising
optimizations builtin, it's not at all intuitive what will
be faster.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Here is the simple code of for loop. Theoretically after for loop, the value of i should increase to 1 but the value is not increasing; i retains the value 0 after the loop also. Can you provide me the reason behind this?
Integer j = 0;
Integer i = 0;
for(; i < m_ParticleNum; ++i)
{
if(m_aOutputParticleID[i] < 0 )
{
m_aOutputParticleID[i] = i;
m_aOutputParticlePosition[i] = bucket[j].Position;
m_aOutputParticleVelocity[i] = bucket[j].Velocity;
m_aOutputParticlePressure[i] = bucket[j].Pressure;
m_aOutputParticleDensity[i] = bucket[j].Density;
m_aOutputParticleTemperature[i] = bucket[j].Temperature;
m_aOutputParticleKineticViscosity[i] = bucket[j].KineticViscosity;
m_aOutputParticleSolidPhaseRate[i] = bucket[j].SolidPhaseRate;
m_aOutputParticleType[i] = bucket[j].Type;
j++;
}
}
If the value of m_ParticleNum is 0, the loop does not execute and so, the value of i stays 0.
Is the value i used in any calculation or output after the loop?
If you are just inspecting i using the debugger, it may be optimised so it doesn't retain a value. There is no guarantee that the compiler has to retain values in unused variables.
Also, if there is any range checking going on which causes the loop to be exited with an exception, the increment of i at the bottom of the loop will be bypassed.
Finally, as i is a user-supplied class Integer, it is possible that some nasty person has defined its operators so the ++ operator is broken/disabled by design and is not incrementing the value.
We really need to see how you are evaluating i after the loop and the declaration of the type Integer to be able to provide a better diagnosis.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have this confusion about conditional statements which may be applicable to almost all programming languages.
Like for instance this C++ code:
int main()
{
char *ptr, arr[]={'C','O','M','P','I','L','E','R','\0'};
ptr = arr;
*ptr = 'Z';
while(*ptr++)
cout << *(ptr-1);
return 0;
}
As what I have learned, a conditional statement executes only when the expression is true. So in this case, this part:
while(*ptr++)
The compiler considers all the characters being true except for the NULL. So meaning to say only NULL is false in this case? And it's alright to do this with characters?:
if('x'){do something}
while(*ptr++)
will keep going till the time ptr does not point to the end of this string which is \0 (Null Terminator) , This same statement also increments ptr to point to next value on each run, so essentially its saying while this condition is true, keep going. And the condition is while ptr still points to an element of arr;
In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days.
Reference
Edit:
But why is it accepting arguments like: while('x')? A letter 'x' is true?
No it doesn't mean the letter itself is true, it means that its not NULL, which is 0. Consider it like this.
while('x')
is the equivalent of saying
while('x'!=0) // so that is perfectly acceptable and understandable
Edit 2:
Here is a simpler example for you to be able to better understand
#include <iostream>
int main()
{
int x=0;
if(x)
{
cout<<"If this is shown, x was not 0.";
}
if(x==0)
{
cout<<"so does it mean x is true? no: It means your condition 'x==0' is true";
}
}
In C, any number apart from 0 is considered true. (0 is false)
If you iterate over an array with *prt++, it checks if the currect index is not zero and increases the pointer.
if ('x') is perfectly valid, but it will always be considered true.
(Remember that char internally is but an 8 bit number and 0 is used to terminate strings. In the example you provided, it is used to iterate over the "string")
And yes, NULL is also considered false (because the address the pointer points to is 0), however, in the example you provided, the pointer gets dereferenced first, so it checks at the place it points to.
It is a relic of C that anything non-zero will evaluate to a boolean true when it is tested, such as your if ('x') above. x has an integer value as it is a character of non-zero value, therefore the expression would evaluate true.
In the case of the pointer iterating over the character array, C 'strings' are always ended in '\0', null, which when the pointer gets there will be the time where the while will fail as null == 0. Not to be confused with '0' as '0' is a character and has an integer value.