Path: utzoo!mnetor!uunet!mfci!root From: root@mfci.UUCP (SuperUser) Newsgroups: comp.lang.c Subject: Re: C Style Message-ID: <371@m3.mfci.UUCP> Date: 27 Apr 88 20:17:10 GMT References: <11216@brl-adm.ARPA> <2111@chinet.UUCP> <4403@garfield.UUCP> <20126@think.UUCP> <601@vsi.UUCP> <364@m3.mfci.UUCP> <4547@ihlpf.ATT.COM> Reply-To: karzes@mfci.UUCP (Tom Karzes) Organization: Multiflow Computer Inc., Branford Ct. 06405 Lines: 122 Summary: Expires: Followup-To: Distribution: Keywords: In article <4547@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes: >In article <364@m3.mfci.UUCP> karzes@mfci.UUCP (Tom Karzes) writes: > >>TRUE should have the same type and value as the constant expression (0 == 0). >>Similarly, FALSE should have the same type and value as the constant >>expression (0 != 0). This principle holds for any language. In the case >>of C, TRUE and FALSE are signed 1 and signed 0, resp. > >Since when does this principle hold for any language?? Take Fortran, for >instance. If I remember correctly, odd numbers were TRUE and even numbers >were FALSE (or vice-versa; it's really been a long time since I used >FORTRAN), since compilers were required to look at only the least >significant bit when checking for true/false values. (This may have been >changed for F77; I'm not sure.) > >There are many other examples I could cite (Icon, LISP, etc.). Your >principle only holds for languages which > >a) Have a boolean type > >and > >b) All logical operations result in that boolean type > >such as Pascal. Many (most?) languages do not conform to these >requirements. First, let me clarify my previous remarks: 1. Obviously they applied to languages for which operations such as comparisons are genuine expressions which return a value with a particular type. This rules out very primitive languages in which comparisons are only permitted in statements which test a condition (although my definitions of TRUE and FALSE could still work if they were simple macros rather than genuine constant expressions). My original message pointed this out, but it was so obvious that I decided not to belabor the obvious and deleted it. Anyway, it's no big deal. 2. Consider the remaining languages which permit truth-valued expressions and variables. In such languages, if TRUE and FALSE are not predefined symbols or special tokens, it is useful to define literals or macros to distinguish their use from, for example, the numbers 1 and 0 for languages which use these for their canonical TRUE and FALSE values. In almost all such languages, 0 == 0 will yield a canonical TRUE and 0 != 0 will yield a canonical FALSE. If TRUE and FALSE are to be defined by a programmer, they should be have the canonical values which are almost always already defined by the language in question. This is independent of whether a unique boolean type is defined by the language (as in Fortran) or whether it is not (as in C). It is also independent of what values "test" as TRUE or FALSE. When testing a value for truth/falsity, depending on the language it may be cast to some appropriate type first or it may not, after which some test is performed (for some languages the test may not even be defined for inappropriate values even if the type is acceptable). However, it should always be the case that TRUE tests true and FALSE tests false. Here is a table of canonical TRUE/FALSE values for various languages: Language True False Type -------- ---- ----- ---- C 1 0 int Fortran .TRUE. .FALSE. LOGICAL Pascal TRUE FALSE BOOLEAN Ada TRUE FALSE BOOLEAN PL/I 1 0 FIXED Bliss 1 0 Lisp T NIL SYMBOL APL 1 0 etc. When testing for truth/falsity, different approaches are taken. In C, every value is merely tested for inequality with 0 (even doubles), with the appropriate type casts being performed. Fortran only defines truth/falsity for .TRUE. and .FALSE., although many implementations define a bit pattern used to represent .TRUE. and .FALSE., and then define a test to determine truth/falsity of non-canonical logicals, integers, etc. (Note that standard F77 only allows .TRUE. and .FALSE. for logicals.) Some implementations test the low-order bit, some test for inequality with zero, etc. Most represent .FALSE. as 0. Some represent .TRUE. as 1, others as -1. But none of this is defined by the standard. Bliss tests the low order bit. Lisp tests for inequality with NIL. Etc, etc. To address the individual points of confusion in the reply to my original message: 1. You obviously don't know much about Fortran. No, Fortran does not define a true/false test (truth predicate) for integers. As I mentioned above, some Fortran compilers choose to expose the internal representation of LOGICALS, and may even define a truth predicate for integers (i.e., they may permit integers to be used directly as logical expressions in logical IF statements, etc.). So what? Even if this WERE defined and required by the standard, it would change nothing. The values .TRUE. and .FALSE. still have type LOGICAL and are still the canonical TRUE/FALSE values of the language. The expression 0 .EQ. 0 evaluates to .TRUE. and 0 .NE. 0 evaluates to .FALSE.. I believe VAX/VMS Fortran allows any integer value to be stored in a logical, and it tests the low order bit when determining truth/falsity. Integers may be tested directly for truth/falsity. Canonical TRUE is -1 and canonical FALSE is 0. Perhaps you thought this was required by the standard (it is not). How parochial. 2. I'm not familiar with icon. However, as I mentioned above, the canonical TRUE/FALSE values for lisp are T and NIL. The truth test used by lisp is inequality with NIL. It happens that both T and NIL have the same data type (SYMBOL), although in object oriented languages such as lisp they could just as easily have different data types (there may well be lisps in which NIL is not regarded as a SYMBOL). 3. I believe I have already dispensed with the notion that a boolean type is required for my principle to hold. Any more questions?