What is the bash "test" command evaluation order? - bash

What is the order in which the test or [ expressions are evaluated in a bash script? Is it the same as the order in which they are written? Are they all evaluated?
In the following example:
if [ expr1 -a -n expr2 ]
will expr2 be evaluated if expr1 is false?

It's been a long time since I used that particular syntax. Nowadays, I prefer:
if [[ expr1 && -n expr2 ]]
since I know that these are short-circuited. The bash man page specifically states:
The && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression.
It doesn't appear to state clearly one way or the other for the [ and test variant (using -a).
However, in the interests of furthering your knowledge and mine (and an indication as to why open source is a good thing), I went trolling through the bash source code.
It turns out that it's not short-circuited in that case. The particular pieces of code are (compressed a bit for readability):
static int or() {
int value, v2;
value = and();
if (pos < argc && argv[pos][0] == '-'
&& argv[pos][1] == 'o' && !argv[pos][2])
{
advance (0);
v2 = or();
return (value || v2);
}
return (value);
}
static int and() {
int value, v2;
value = term();
if (pos < argc && argv[pos][0] == '-'
&& argv[pos][1] == 'a' && !argv[pos][2])
{
advance (0);
v2 = and();
return (value && v2);
}
return (value);
}
You can see in both those cases that it continues to interpret the expressions regardless of the state of the first expression.
That was from bash 2.5 but I've just checked the 4.1 source as well and it hasn't changed. Source was pulled straight from the horse's mouth.
So. bottom line: it appears that all sub-expressions are evaluated when using -a and -o with test or [.

Related

Can map::find and iterator::second be used in one condition

I have such a piece of code:
std::map<int, int> mp;
// do something
auto itor = mp.find(some_value);
if (itor != mp.end() && itor->second == some_other_value) {
// do something
}
I'm worrying about which expression would be evaluated first, itor != mp.end() or itor->second == some_other_value?
If the second one is evaluated firstly (because of some compiler-optimization maybe?), it might get an undefined behavior because itor == mp.end() may be true.
Should I worry about this issue so that I have to code like this:
if (itor != mp.end) {
if (itor->second == some_other_value) {
// do something
}
}
No worries; your code is fine.
If the first condition of if (a && b) is false, then the second condition is not evaluated.
Look up "short-circuit evaluation"
Wikipedia has some info.
Logical And - && - expression is evaluated left to right so itor != mp.end() will be evaluated initially. Moreover, it returns true only if both expressions return true, hence if the first one is false the second one is not checked.
so the first case should work.

expression evaluation confusion in c++

Can somebody please explain to me what is going on here?
I have this line of code:
if ( pt->child == NULL && pt->visits < cutoff+1 || depth > 5 )
and I'm getting a g++ compiler warning:
warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]|
What is it trying to warn me of? And worse, if I put in the "obvious" parens, like so:
if ( ( pt->child == NULL && pt->visits < cutoff+1 ) || depth > 5 )
I get a different behavior -- indicating I really did do something wrong in the first expression. Arithmetic operators have higher precedence over comparisons which have higher precedence over boolean operators where && has higher precedence than ||, right?
What am I missing?
Just like the numeric operators + and *, the logical operators have different precedence. So the order of evaluation of a logical statement will not necessarily be strictly left to right, but will instead evaluate && first and || 2nd. This has been the source of so much confusion and error that the compiler will emit this warning unless you explicitly surround the elements with parentheses.
What going on here? I think in this case it's erroneous because if you make g++ dump it's internal structures
this
if ( pt->child == NULL && pt->visits < cutoff+1 || depth > 5 )
printf("Hello World");
equates to this
D.3367 = pt->child;
if (D.3367 == 0B) goto <D.3368>; else goto <D.3364>;
<D.3368>:
D.3369 = pt->visits;
D.3370 = cutoff + 1;
if (D.3369 < D.3370) goto <D.3365>; else goto <D.3364>;
<D.3364>:
if (depth > 5) goto <D.3365>; else goto <D.3366>;
<D.3365>:
printf ("Hello World");
<D.3366>:
Which does exactly what you would expect.

Why SSI condition != || != doesn't work?

I can't get working this conditional expression
<!--#if expr="$DOCUMENT_NAME!=index.html || $DOCUMENT_NAME!=links.html" -->
while this one without ! before = works perfect
<!--#if expr="$DOCUMENT_NAME=index.html || $DOCUMENT_NAME=links.html" -->
What's the problem? I get no error simply != doesn't work though || with other condition but works for single condition.
This is because = and != are hardly the same operator. Note that, by De Morgan's law (which I also explained in this old post),
a != b || c != d
is equivalent to
a = b && c = d
which is never true for x = a && x = b where a != b.
Changing the binary operator requires changing the conditionals as well to be equivalent.
Thus, by the above logic,
$DOCUMENT_NAME!=index.html || $DOCUMENT_NAME!=links.html
is equivalent to
$DOCUMENT_NAME=index.html && $DOCUMENT_NAME=links.html
which cannot be true as $DOCUMENT_NAME can be "index.html" or "links.html" but not both.
However, the 2nd snippet,
$DOCUMENT_NAME=index.html || $DOCUMENT_NAME=links.html
"works" because there is not the logical never-true fallacy mentioned above. It will be true when $DOCUMENT_NAME is either "index.html" or "links.html".
Some languages/values will violate the above equivalency .. but that is another topic.

What is the difference between 'and, or' and '&&, ||'? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
PHP - and / or keywords
Ruby: difference between || and 'or'
What is the difference between this:
a=20
b=30
if (a > 10 && b > 10)
puts a
end
and this:
if (a > 10 and b > 10)
puts a
end
and also explain difference between "||" and "or"
The answer relates to the PHP tag that has been assigned to this question, but has been deleted afterwards
They are the same with one small difference. The and and or operator have a lower precedence compared to && and ||.
Take this example from the manual:
// The result of the expression (true && false) is assigned to $g
// Acts like: ($g = (true && false))
$g = true && false;
// The constant true is assigned to $h and then false is ignored
// Acts like: (($h = true) and false)
$h = true and false;
You can read about operators in PHP's documentation.
Only the difference in precedence
As you can see from the precedence table for Ruby, the difference is also precedence, as it is in PHP: and and or have lower precedence than && and ||.
But there is a slight difference from PHP: in Ruby, and and or have the same precedence.
I got the answer. Please go and read it. this is what i'm expect it.
http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/
Thanks all of your efforts

IF statement formatting best-practise, what's your style?

Looking to improve my IF statement, and I want to keep my code looking pretty
This is what I am currently doing, is it readable, any room for improvement?
SomeObject o = LoadSomeObject();
if( null == o
||
null == o.ID || null == o.Title
||
0 == o.ID.Length || 0 == o.Title.Length
)
I don't have anyone to ask around. That's why I came here in first place. Please don't close my question :(
I always try and avoid complex boolean expressions for the sake of the next guy, but if I had to write an expression that didn't easily go on one line I would format it as follows:
if (value1 == value2 ||
value3 == value4 ||
value5 == value6 ||
value7 == value8) {
executeMyCode();
}
Your verbosity is leading to a less readable code, I think the following format is best:
if ( null == o || null == o.ID || null.Title || 0 == o.ID.Length || 0 == o.Title.Length )
{
// do stuff
}
We all have high resolution/widescreen displays for a reason, there's no reason to lock your code at some horribly short syntax. Also, I would simply create a function named IsIDEmpty so that the code could look like
if ( IsIDEmpty(o) )
{
// do stuff
}
to keep the code simpler & cleaner. The function would perform the actual checks and return a boolean. I'm sure this is something you might have re-use for anyways, plus it serves as a simple way for code to be more self documenting/commenting.
For the simplest formatting of what you have, I would go with one per line.
if(null == o
|| null == o.ID
|| null == o.Title
|| 0 == o.ID.Length
|| 0 == o.Title.Length)
Even better would be if you could refactor the condition such that it fits on one line. I find that a large number of || or && is usually difficult to read. Perhaps you can refactor it out into a function and be left with:
if(myFunction(...))
My rule of thumb: Avoid any format that a semi-smart auto-formatter can't reproduce.
Having a defined set of formats and a automated tool/template/configuration that actually produces code in that format is a big plus, in my opinion.
And if your code is still unreadable after it has been auto-formatted, then chances are that you need to refactor anyway.
I would either put it all on one line if it fits (which this one clearly doesn't). With this, I would put the || consistently at the start or end of line:
if( null == o ||
null == o.ID ||
null == o.Title ||
0 == o.ID.Length ||
0 == o.Title.Length
)
or
if( null == o
|| null == o.ID
|| null == o.Title
|| 0 == o.ID.Length
|| 0 == o.Title.Length
)
You could have >1 condition on a line, the positioning of || is more important I think.
I'm ignoring the fact that null.Title doesn't seem to make much sense
I find it quite distracting, to be honest. Mostly because the '||' start making funny patters.
I much rather prefer something like
if ( o == null || o.ID == null || null.Title ||
o.ID.Length == 0 || o.Title.Length )
or even better, keep it in a single line if possible.
I think it's pretty unreadable.
The affection of putting the constant first always seems a bit odd to me - most compilers can be persuaded to warn if they find an assignment in a conditional.
Then you're testing for null for two different things, then for zero length for two different things - but the important thing is not the length check, but the member you're checking. So I'd write it as
if (o == null ||
o.ID == null || o.ID.length == 0 ||
o.Title == null || o.Title.Length == 0)
Rather than making up a standard for just this one question - I would suggest adopting an existing coding standard for whatever language you are using.
For example:
GNU Coding Standards
http://www.gnu.org/prep/standards/
Code Conventions for the Java Programming Language
http://java.sun.com/docs/codeconv/
.NET Framework General Reference Design Guidelines for Class Library Developers
http://msdn.microsoft.com/en-us/library/czefa0ke.aspx
Generally I'm with TravisO on this, but if there are so many conditions in your if() statement that it just gets crazy long, consider putting in its own little function instead:
bool wereTheConditionsMet()
{
if( NULL == 0 )
return true;
if( NULL == o.ID )
return true;
: : // and so on until you exhaust all the affirmatives
return false;
}
if ( wereTheConditionsMet() )
{
// do stuff
}
It is a lot easier to convey the intent of a well-named predicate function than an endless string of ||s and &&s.
It is not readable.
This is how I do Really Long Ifs(or those I have to twiddle a lot).
if(
o == null ||
o.ID == null ||
o.Title == null ||
o.ID.Length == 0 ||
o.Title.Length == 0
)
For yours, I would do a single line.
if(o == null || o.ID == null || o.Title == null || o.ID.Length == 0 || o.Title.Length == 0)
Or, if you are using C++, I'd do something like this:
if(!o)
{}
if(! (o.ID && o.Title && o.Length))
{}
...since it separates creation from correctness.
However, caveat emptor, I've been accused of bloated LOC due to my fondness for newlines.
Use an automated code formatter, and configure it appropriately.
Write a method like isPresent(String) that checks the String argument for not null and for not empty (zero length).
Rewrite the original conditional to use the new isPresent(String) method, probably all on one line.
I usually do something like:
if(x < 0 || x >= width
|| y < 0 || y >= height)
{
/* Coordinate out of range ... */
}
The first y and x line up in a monospace font, which is nice, and I'm not confused by half-indentions.
This method works best when doing similar comparisons. Otherwise, I usually split up my if's.

Resources