Peter said:
Peter J. Holzer wrote:
(5) That "special false". I was going nuts trying to figure out what
was different between
[ '' in string context, 0 in numeric context ] [...]
Anyone who applies a numeric operator to a logical value and expects
consistent results is asking for trouble. [...]
In strongly-typed languages you would get a compiler or run-time
error/warning, however perl is a scripting language and is built to be
flexible, assumes you know what you're doing and will silently oblige
even the most horrendous abuses.
You actually have the same issue in C: false is defined as 0 and true is
!false.
However, in C, !0 is defined as 1.
This is where lots of people make mistakes in C.
You seem to be one of them.
if(a) is not the same as
if(a == !0)
I didn't say that. I said !0 is the same thing as 1 which means, that
if (a == !0)
is exactly the same as
if (a == 1)
While
if (a)
is the same thing as
if (a != 0)
Obviously (a != 0) and (a == 1) are not the same thing.
Original C compilers had an easy way of doing conditionals; they would
assign a variable to a register and then branch on the Z flag.
This may have been true on the PDP-11, although I doubt it. It certainly
wasn't a common feature of CPUs at the time. Most only set the flags as
the result of some computation, not a simple MOV. (There is a special
TST instruction to set the status flags depending on the contents of a
register)
This worked because !0 is any value with any bit set.
No. !0 is not any non-zero value. !0 is exactly 1. Any non-zero value is
treated as "true".
Yes, there are no bools, but conditionals in C work on zero and non-zero
integers.
Your "but" sounds like there is a contradiction. There isn't. C doesn't
have a boolean type and you can use any scalar type (not just
integers) where a true/false decision is needed (I think this is what
you mean by "conditional" - correct me if I'm wrong). The result of the
relational, equality and logical operators is defined as having type
int, thus there is no "crossing a type boundary" when you use them in an
arithmetic expression. Such a type boundary may exist in the mind of a
Pascal programmer, but it doesn't exist in C.
This example would work, however in some C compilers I have used
x=(2>0)+5 would always return 7.
Then they were not C compilers.
Each of the operators < (less than), > (greater than), <= (less than
or equal to), and >= (greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false.89) The result has
type int.
(ISO-9899:1999. A similar definition is in Appendix A, section
7.6 of K&R I, German translation (I don't have the original)
This is because the compiler worked with not 0 being true, and the
cheapest comparison on a particular platform is sub.
So the result of
(-2 > 0)
would be -2 (i.e., true)? I think you should think about this a bit
more.
This doesn't break comparison operators,
If (-2 > 0) is true that's pretty broken by any measure. If a compiler
produces a different result than the C specification says it should, it
is still broken.
Sorry, you're mistaking C semantics for Perl.
No, I'm not. I don't see where you see any C semantics in the paragraph
above. C simply doesn't have scalars which may be an integer and a
string at the same time. This is quite Perl-specific.
Perl does not treat scalars as integers and so it's conditionals are
more complex (and yes hacky) than C. Especially the one you don't
like, which is defining the behavior of a string being used in a
condition.
Who said I don't like it? I never said such a thing. I don't even think
it is very complex. The number 0, the strings '' and '0' and the undef
value are false, all other scalars are true.
Perl defines false and any other value is true.
You don't seem to understand the difference between
1) what is recognised as true in a conditional expression and
2) what a comparison or logical operator returns as a true value
These are not the same thing.
This is not an omission. In this way it does behave exactly the same
way C does.
No it is not.
C does define that the result of the expression (0 < 1) is 1. If your
compiler produces a different result, it is broken.
Perl only defines that the result of the expression (0 < 1) must be
true. It could be 1, -1, 'true', 42, a reference to a hash, whatever.
However, every version of perl (note: lower case 'p') since at least
perl4 (probably perl1) has always returned 1 as the true value for the
comparison operators (==, !=. <. >. <=, >=, eq, ne, lt, gt, le, ge) and
the logical negation (!, not). It is not clear to me whether this is
undocumented because @Larry want to keep the option of changing it one
day (in this case, why is the false value documented? The ''/0 mixture
is rather bizarre and it seems much more likely that one would like to
change that in some future revision of the language), or whether it is
simply undocumented because it's the same as in C and "people know that
anyway, so we don't have to write it down". (Perl documentation has
become more self-sufficient over the years, but originally it assumed a
lot of general Unix knowledge and there are still spots which are only
comprehensible if you have a background as a Unix/C programmer - this
might be one of them)
hp