nagle@well.UUCP (John Nagle) (09/22/89)
I would like to suggest that the time has come to standardize the Boolean values in C. Most programs have definitions of these, but they differ and clash. As the typing rules become ever tighter, and the number of commercial libraries available grows, this becomes a more and more serious problem. Commercially published libraries have spellings such as "TRUE", "true", and "True", forms of definition including "#define", "const", and "enum", and Boolean types (spelled variously) defined as "char", "unsigned char", "unsigned short", and "enum". This has got to stop. I would suggest that the standardized definition be const boolean (false=0, true=1); which follows the convention that predefined types in C are all lower case. The explicit values for "false" and "true" are given, although redundant, to make the point that those values are part of the specification and are not an accident of the ordering in the definition. It should be mandated that this definition be a part of the C and C++ header files, preferably in an ANSI-specified file. "stddef.h" seems a likely choice, but this is open to discussion. If it's too late to fix this in C, it should be fixed in C++, where typing is taken more seriously. John Nagle
blarson@basil.usc.edu (bob larson) (09/22/89)
In article <13730@well.UUCP> nagle@well.UUCP (John Nagle) writes: > > I would like to suggest that the time has come to standardize the >Boolean values in C. [...] > I would suggest that the standardized definition be > const boolean (false=0, true=1); Why don't we just change the languae so it has this stuff built in? Perhaps we can find a way that dosn't add more keywords to the language... the little-known keyword "int" should be able to do double-duty as boolean, and the keywords 0 and 1 should work just fine as false and true. Let's see what other changes are needed to the languge... none. Gee, it seems that maybe this was one of the uses theese keywords were designed for. :-) -- Bob Larson Arpa: blarson@basil.usc.edu Uucp: usc!basil!blarson
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/22/89)
In article <13730@well.UUCP> nagle@well.UUCP (John Nagle) writes: > I would suggest that the standardized definition be > const boolean (false=0, true=1); I don't know what that is supposed to mean; it's not C. > It should be mandated that this definition be a part of the C >and C++ header files, preferably in an ANSI-specified file. The result of a nominally Boolean expression in C is well-defined; it has int type with value 1 for true, 0 for false. >"stddef.h" seems a likely choice, but this is open to discussion. Not really. There is no problem insofar as the C Standard goes; "bool", "true", etc. are not reserved words and have no special meaning. The problem you describe comes about only when you #include headers for several unrelated (or at least uncoordinated) libraries. In such a case, this is merely a small part of a name-space clash problem. You should address the general problem instead of one small aspect of it.
newsuser@lth.se (LTH network news server) (09/22/89)
In article <13730@well.UUCP> nagle@well.UUCP (John Nagle) writes: > > I would like to suggest that the time has come to standardize the >Boolean values in C. I completely agree that a boolean data type is needed in C++. I think the definition should define the following properties: 1. The data type is called "boolean". 2. The allowed values are "false" and "true". 3. int(false) = 0 and int(true) = 1 4. boolean(0) = false, other values are true I do not know if implicit conversion boolean <==> int should be allowed. In the time before C++ 2.0, it was quite common to define a boolean type as an enumeration: enum boolean {false, true}; Unfortunately (in this case), C++ no longer allows implicit conversion int ==> enum, so the result of a comparison must be explicitly type cast: boolean b; b = (i == 3); // warning b = boolean(i == 3); // ok This is rather clumsy. We cannot define our own operator functions on the boolean data type, because one of the arguments must be a class object. boolean operator == (boolean x, boolean y) {...} // error I do not understand exactly why this restriction is required, but apparently it is. Please enlighten me. What remains is to define a class for boolean. This is not easy to make as efficient as the built in types, but the problem is mostly in the lack of optimization in the code generators. I have tried; you will find my attempt to define a boolean below. Note that I have not defined the operators && and || -- I do not think we can achieve the "short circuit" evaluation we're used to with a user-defined operator. Dag Michael Bruck -- Department of Automatic Control Internet: dag@control.lth.se Lund Institute of Technology P. O. Box 118 Phone: +46 46-108779 S-221 00 Lund, SWEDEN Fax: +46 46-138118 ============================================================================== // Boolean data type enum {false, true}; class Boolean { public: Boolean() { val = false; } Boolean(int i) { val = (i != false); } Boolean(const Boolean& b) { val = b.val; } // Any non-zero value is true; default value is false. operator int() { return val; } // Type cast boolean => integer. void operator &= (const Boolean& b) { val &= b.val; } void operator |= (const Boolean& b) { val |= b.val; } void operator ^= (const Boolean& b) { val ^= b.val; } // Operator assignment. friend Boolean operator & (const Boolean&, const Boolean&); friend Boolean operator | (const Boolean&, const Boolean&); friend Boolean operator ^ (const Boolean&, const Boolean&); friend Boolean operator ! (const Boolean&); friend Boolean operator == (const Boolean&, const Boolean&); friend Boolean operator != (const Boolean&, const Boolean&); // These operators need access to the internal representation. private: int val; Boolean(long i) { val = int(i); } // no check }; inline Boolean operator & (const Boolean& p, const Boolean& q) { return long(p.val & q.val); } inline Boolean operator | (const Boolean& p, const Boolean& q) { return long(p.val | q.val); } inline Boolean operator ^ (const Boolean& p, const Boolean& q) { return long(p.val ^ q.val); } inline Boolean operator ! (const Boolean& p) { return long(!p.val); } inline Boolean operator == (const Boolean& p, const Boolean& q) { return long(p.val == q.val); } inline Boolean operator != (const Boolean& p, const Boolean& q) { return long(p.val != q.val); } // Note: there are no && and || operators. Boolean f(Boolean b) { return !b; } main() { Boolean p, q, r; r &= p; r = p & q; r = f(p); } -- Department of Automatic Control Internet: dag@control.lth.se Lund Institute of Technology P. O. Box 118 Phone: +46 46-108779 S-221 00 Lund, SWEDEN Fax: +46 46-138118
dog@cbnewsl.ATT.COM (edward.n.schiebel) (09/22/89)
From article <13730@well.UUCP>, by nagle@well.UUCP (John Nagle): > I would like to suggest that the time has come to standardize the > Boolean values in C. HERE HERE!!! -Ed Schiebel.
nagle@well.UUCP (John Nagle) (09/23/89)
Correction: the definition should have read:
> enum boolean (false=0, true=1);
Doug Gwin at BRL points out that namespace clashes are a more
general problem in C. But this isn't a namespace-control problem.
It's not that we want every package to have its own definition of
"boolean", all kept straight in some way and with conversion functions
between package A's "boolean" and package B's "boolean" somehow provided.
"boolean" really ought to be part of the language, and the logical
operators should return results of type "boolean", but it's too late in
the history of C/C++ for that. Nevertheless, we should at least have
a consistent definition within the current language structure.
John Nagle
henry@utzoo.uucp (Henry Spencer) (09/23/89)
In article <13730@well.UUCP> nagle@well.UUCP (John Nagle) writes: > I would like to suggest that the time has come to standardize the >Boolean values in C... They are already standard. Integer nonzero means true. Integer zero means false. There is not the slightest hope of changing this now. Furthermore, it's not clear that it's worth the trouble. -- "Where is D.D. Harriman now, | Henry Spencer at U of Toronto Zoology when we really *need* him?" | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
ian@mva.cs.liv.ac.uk (09/24/89)
In article <1989Sep22.073138.19684@lth.se>, newsuser@lth.se (LTH network news server) writes: > I completely agree that a boolean data type is needed in C++. I > think the definition should define the following properties: > > 1. The data type is called "boolean". > That's just what _you_ want to call it! Why not call it `bool' or `logical' or even `int'? > 2. The allowed values are "false" and "true". > Why not call them `f' and `t' or `F' and `T' or even `0' and `1'? > 3. int(false) = 0 and int(true) = 1 > Well, int (0) = 0 and int (1) = 1. > 4. boolean(0) = false, other values are true > Wouldn't it be great for conditionals in C to be false if they are testing integer 0 and to be true if they are testing any other integer? That way we could use integers instead of a new boolean type. Oh, looks like they already do that! Why do we need to introduce a new data type to do the job of a data type we already have, but in a more complex way? Ian Finch Janet: ian@uk.ac.liv.cs.mva --------- Internet: ian%mva.cs.liv.ac.uk@cunyvm.cuny.edu UUCP: ...mcvax!ukc!ian@uk.ac.liv.cs.mva =============================================================================== What's a word processor? Well, you know what a food processor does to food ...
rhg@cpsolv.UUCP (Richard H. Gumpertz) (09/24/89)
If the type bool were a new BUILT-IN type then the compiler implementor could decide what width (and representation values) it should have INDEPENDENTLY from deciding int, char, etc. This might result in more efficient representation on a portable basis. The casting rules from integral types to bool would no longer catch poor programmers who write: #define bool char ... int mumble(); ... bool failed; failed = mumble(); This fails for 8-bit chars when mumble returns an error code of 0x300. The programmer really wanted: failed = (mumble() != 0); or failed = (!!mumble()); or failed = (mumble() ? true : false); If type bool were built in, then the (implicit) cast from integral types to bool would include the "!= 0" test automatically if needed. Also, the precise representation of bool would now be implementor-defined: it would only be required that casts of bool to integral types return 0 or 1; the internal representation of bool might be different. -- ========================================================================== | Richard H. Gumpertz: ...uunet!amgraf!cpsolv!rhg | | Computer Problem Solving, 8905 Mohwak Lane, Leawood, Kansas 66206-1749 | ==========================================================================
wjf@attctc.Dallas.TX.US (Jesse Furqueron) (09/25/89)
In article <13730@well.UUCP>, nagle@well.UUCP (John Nagle) writes: > > I would like to suggest that the time has come to standardize the > Boolean values in C. Most programs have definitions of these, but they > differ and clash. As the typing rules become ever tighter, and the number xyzzy!! and text disappears... > > I would suggest that the standardized definition be > If it's too late to fix this in C, it should be fixed in C++, where > typing is taken more seriously. > > John Nagle I would suggest rather than FALSE = 0 and TRUE = 1, that the "real" definition of TRUE is not FALSE (TRUE = not 0), i.e. TRUE = !0. Therefore the following #define FALSE 0 #define TRUE !0 or for c++ folks const boolean (FALSE=0, TRUE=!0); I believe (if this tired and aged memory serves me correctly) that somewhere K&R refers to this being the evalutations used in if and while statements. Jesse Furqueron VISystems 11910 Greeneville Suite 300 LB 29 Dallas, Tx. 75243 (214) 907-8080 ------------------------------------------------------------------------------- As always, the opinions expressed by myself are not necessarily those of my employer... maybe one of these days they'll learn to listen!!! -------------------------------------------------------------------------------
dhesi@sun505.UUCP (Rahul Dhesi) (09/25/89)
(The referenced article had a follow-up header of "poster", which I think is a nasty thing to have done.) In article <9464@attctc.Dallas.TX.US> wjf@attctc.Dallas.TX.US (Jesse Furqueron) writes: >#define FALSE 0 >#define TRUE !0 I suggest that defensive programmers eschew these constants because the temptation to say if (x == TRUE) ... may overcome you some day and you will suffer, unless you can universally guarantee that you didn't absent-mindedly do something like x = isdigit(c); If, on the other hand, you are willing to either be careful to always say x = (isdigit(c) != 0); or if you alternatively define #define ISTRUE(x) (x) #define ISFALSE(x) (!(x)) and say if (ISTRUE(x)) ... if (ISFALSE(y)) ... instead then the use of TRUE and FALSE is not so dangerous. Best is just think binary and say: x = 0; /* x is false */ y = 1; /* y is true */ and for testing use if (x) ... /* if x is true */ if (!y) ... /* if y is false */ If you really must define a macro, try: #define ONE 1 #define ZERO 0 Now if you see if (x == ONE) ... you immediately realize that this could fail to work. The problem is that in C any nonzero value is considered to be true when tested in a boolean context, so #define TRUE 1 is misleading. In a richer language you could perhaps say: #define TRUE [-inf..-1, 1..+inf] Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com> UUCP: oliveb!cirrusl!dhesi
karzes@mfci.UUCP (Tom Karzes) (09/26/89)
In article <9464@attctc.Dallas.TX.US> wjf@attctc.Dallas.TX.US (Jesse Furqueron) writes: >I would suggest rather than FALSE = 0 and TRUE = 1, that the "real" definition >of TRUE is not FALSE (TRUE = not 0), i.e. TRUE = !0. Therefore the following > >#define FALSE 0 >#define TRUE !0 That's silly. You should either assume the values that C guarantes: #define FALSE 0 #define TRUE 1 Or else assume nothing and let the compiler figure it out each time: #define FALSE (0 != 0) #define TRUE (0 == 0) Your mistake is that you're confusing C's truth test (!= 0) with its canonical true and false values (F=0, T=1). In general, the canonical true and false values in a language must behave appropriately under its true test, but there may be non-canonical values which do the same. In C, there is only one integral false value. However, there are also false pointer and floating point types. In that sense, the "!= 0" test in itself says nothing about canonical false being an integer zero. Since they should only be defined once, I think it's a bit extreme to use the latter definitions shown above, but they do provide the proper justification for 0 and 1, which are best thought of as constant folded versions of these (or similar constant expressions which generate canonical true and false values without depending on what those values are).
karzes@mfci.UUCP (Tom Karzes) (09/26/89)
In article <895@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >(The referenced article had a follow-up header of "poster", which I >think is a nasty thing to have done.) I agree. >I suggest that defensive programmers eschew these constants because the >temptation to say > > if (x == TRUE) ... > >may overcome you some day and you will suffer... I agree that this sort of thing does happen, particularly in a language like C which doesn't support a distinct boolean data type but does support boolean operations defined on integers. However, I feel that it is primarily a matter of understanding and engineering discipline. Proper use of a user defined boolean data type will only attempt to represent canonical true and false values in that data type. It should be sufficient to define: typedef int bool; #define FALSE 0 #define TRUE 1 and to then only use bool to hold TRUE or FALSE (which includes values generated by comparisons, !, &&, ||, etc.). Under this usage, the following constructs should never appear for bool's b, b1, and b2: bad form preferred equivalent ---------------- -------------------- b == FALSE ! b b != FALSE b b == TRUE b b != TRUE ! b b ? TRUE : FALSE b b ? FALSE : TRUE ! b b1 ? FALSE : b2 (! b1) && b2 b1 ? TRUE : b2 b1 || b2 b1 ? b2 : FALSE b1 && b2 b1 ? b2 : TRUE (! b1) || b2 Expressions of type bool should not be used as integer expression unless explicitly case to type int, to indicate that the F=0, T=1 behavior is being assumed. The need for this shouldn't arise very often (only in tight little pieces of code where you want to do something like optionally add 1 to a number, depending on a bool value, and you want it to be really tight code so you simply add the cast bool, as opposed to "b ? 1 : 0").
garys@bunker.UUCP (Gary M. Samuelson) (09/26/89)
In article <1885@mva.cs.liv.ac.uk> ian@mva.cs.liv.ac.uk writes: >Wouldn't it be great for conditionals in C to be false if they are testing >integer 0 and to be true if they are testing any other integer? That way >we could use integers instead of a new boolean type. Oh, looks like they >already do that! In any argument, I find I will tend to take the side opposite that which is supported largely by ridicule and sarcasm. >Why do we need to introduce a new data type to do the job of a data type >we already have, but in a more complex way? It seems to me that your arguments (such as they are) would apply equally to "short" and "long" (perhaps even "char"). Why do you think I should use 32 bits ("int" in some environments) when 1 would do? I favor the addition of "boolean" to "C" -- it's only logical. Gary Samuelson
tneff@bfmny0.UU.NET (Tom Neff) (09/26/89)
There is so much code that already thinks it has to - and can - define what "boolean" is, that adding a reserved "boolean" type would probably be greeted with more groans than cheers. Nor does much of this existing code make any room for 1-bit implementations, from what I've seen. I think that at MOST, "boolean," "TRUE" and "FALSE" should have the same status as "NULL," i.e., some (new) standard header like <bool.h> should define them if you bother to include it. And the guidance would suggest saying #define boolean int #define TRUE 1 #define FALSE 0 although I have always smiled on clevernesses like #define TRUE (1==1) #define FALSE (1==0) -- 'The Nazis have no sense of humor, so why -| Tom Neff should they want television?' -- Phil Dick |- tneff@bfmny0.UU.NET
rhg@cpsolv.UUCP (Richard H. Gumpertz) (09/27/89)
The biggest advantage of a built-in boolean type would be that casts TO it would test for zero/non-zero rather than just trucating the high-order bits if sizeof(source) is bigger than sizeof(bool). Also, (bool)X & (bool)Y would do "right" thing even if X was 4 and Y was 32. In other words, & would be equivalent to && for type bool except that both operands would be evaluated. -- ========================================================================== | Richard H. Gumpertz: ...uunet!amgraf!cpsolv!rhg | | Computer Problem Solving, 8905 Mohwak Lane, Leawood, Kansas 66206-1749 | ==========================================================================
wen-king@cit-vax.Caltech.Edu (King Su) (09/27/89)
In article <7701@bunker.UUCP> garys@bunker.UUCP (Gary M. Samuelson) writes: <In any argument, I find I will tend to take the side opposite that which >is supported largely by ridicule and sarcasm. You shouldn't go around exposing your weakness like that; you can be manipulated into taking any side. :-) >>Why do we need to introduce a new data type to do the job of a data type <>we already have, but in a more complex way? > <It seems to me that your arguments (such as they are) would apply >equally to "short" and "long" (perhaps even "char"). Why do you think <I should use 32 bits ("int" in some environments) when 1 would do? >I favor the addition of "boolean" to "C" -- it's only logical. It doesn't have to be 32 bits. Besides, using 32 bits is perfectly OK if it makes the program faster and if speed is what you are after. If space is more important, you can do with 1 bit if you use bit field. We can do just fine with what we got, so the question is why is boolean needed and why is it, as you say, logical (perhaps you forgot a smiley). -- /*------------------------------------------------------------------------*\ | Wen-King Su wen-king@vlsi.caltech.edu Caltech Corp of Cosmic Engineers | \*------------------------------------------------------------------------*/
wen-king@cit-vax.Caltech.Edu (King Su) (09/27/89)
In article <393@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes: >The biggest advantage of a built-in boolean type would be that casts TO it <would test for zero/non-zero rather than just trucating the high-order bits >if sizeof(source) is bigger than sizeof(bool). Also, (bool)X & (bool)Y would <do "right" thing even if X was 4 and Y was 32. In other words, & would be >equivalent to && for type bool except that both operands would be evaluated. Why not just do: #define bool(a) (!!(a)) Then just use bool(X) whenever you wanted to use (bool)X. -- /*------------------------------------------------------------------------*\ | Wen-King Su wen-king@vlsi.caltech.edu Caltech Corp of Cosmic Engineers | \*------------------------------------------------------------------------*/
peter@ficc.uu.net (Peter da Silva) (09/28/89)
Rather than add a boolean type, make bitfeilds more like first-class objects: typedef int boolean:1; boolean x; /* allocates, say, 1 byte */ boolean y, z; /* allocates a byte each, so you can take an addr */ { register boolean a,b,c; /* Allocates 1 byte for all: no addr needed */ struct foo { boolean bar, baz; }; /* sizeof(foo) == 1 */ ... -- Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation. Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-' "That is not the Usenet tradition, but it's a solidly-entrenched U delusion now." -- brian@ucsd.Edu (Brian Kantor)
foessmei@lan.informatik.tu-muenchen.dbp.de (Reinhard Foessmeier) (09/28/89)
In article <12067@cit-vax.Caltech.Edu> wen-king@cit-vax.UUCP (Wen-King Su) writes: >... >It doesn't have to be 32 bits. Besides, using 32 bits is perfectly OK >if it makes the program faster and if speed is what you are after. If >space is more important, you can do with 1 bit if you use bit field. >We can do just fine with what we got, so the question is why is boolean >needed and why is it, as you say, logical (perhaps you forgot a smiley). >-- ^Ci tiu diskuto iris tute alian This discussion has taken a road com- vojon ol mi komence imagis. ^Cu pletely different from what I first ne unu el la precipaj avanta^goj imagined. Wouldn't one of the main de C-tipo `boolean' estus, ke ^gi advantages of a `boolean' type in C ebligus pli striktan kontrolon de be the possibility for stricter type tipoj (pli ol la ^sparo de kelkaj checking (rather than saving a few bitoj)? Kompreneble, tiuj belaj bits)? Of course, such beloved con- konstrua^joj "x<y<z<u" tiam ne structs as "x<y<z<u" would no longer estus eblaj, se ne permesi ankaw be possible, unless comparison of komparon de bule-oj. `boolean's would be permitted. >/*------------------------------------------------------------------------*\ >| Wen-King Su wen-king@vlsi.caltech.edu Caltech Corp of Cosmic Engineers | >\*------------------------------------------------------------------------*/ __________ Reinhard F\"ossmeier, Technische Univ. M\"unchen | UNOX is a trademark of foessmeier@infovax.informatik.tu-muenchen.dbp.de | "Union Deutsche [ { relay.cs.net | unido.uucp } ] | Lebensmittelwerke GmbH"
pl@etana.tut.fi (Lehtinen Pertti) (09/28/89)
From article <12070@cit-vax.Caltech.Edu>, by wen-king@cit-vax.Caltech.Edu (King Su): > > #define bool(a) (!!(a)) > > Then just use bool(X) whenever you wanted to use (bool)X. > Then suddenly just behind the corner cames C-compiler from ACME-corporation and realizes '!!a' -> negation of negation is same as original -> we can optimize it away. Nice, isn't it. And too real too. -- pl@tut.fi ! All opinions expressed above are Pertti Lehtinen ! purely offending and in subject Tampere University of Technology ! to change without any further Software Systems Laboratory ! notice
quiroz@cs.rochester.edu (Cesar Quiroz) (09/28/89)
In <8862@etana.tut.fi>, pl@etana.tut.fi (Lehtinen Pertti) suggested that the bogus "optimization" | Then suddenly just behind the corner cames C-compiler from | ACME-corporation and realizes '!!a' -> negation of negation is | same as original -> we can optimize it away. could make !!a be just good old a, instead of guaranteed 0 or 1. Either such compiler exists, in whose case it is broken and we should not lose much sleep over it, or it doesn't. My impression is that it doesn't, barring better information from the poster. That would be a really poor case of arguing from the incompetence of a non-existent compiler. Madness lies that way; opposing or supporting something just because some compiler could, perhaps, maybe, if we try hard enough, screw up the language is ridiculous. If you know of a compiler that makes that mistake, expose it to the community, that may get it fixed (or at least may make it reasonable to be extra cautious when having to use the critter). Else, please don't invent it just for the sake of argument. -- Cesar Augusto Quiroz Gonzalez Department of Computer Science University of Rochester Rochester, NY 14627
jeenglis@nunki.usc.edu (Joe English) (09/29/89)
pl@etana.tut.fi (Lehtinen Pertti) writes: >From article <12070@cit-vax.Caltech.Edu>, by wen-king@cit-vax.Caltech.Edu (King Su): >> #define bool(a) (!!(a)) >> >> Then just use bool(X) whenever you wanted to use (bool)X. > Then suddenly just behind the corner cames C-compiler from > ACME-corporation and realizes '!!a' -> negation of negation is > same as original -> we can optimize it away. But that won't happen with a working compiler, since !!a is not equivalent to a. This macro doesn't solve the perceived problem, though: what is wanted is a first-class boolean type (don't ask me what it was wanted *for*, I don't know...) This solution requires explicit casting of every boolean expression. --Joe English jeenglis@nunki.usc.edu.
tim@cayman.amd.com (Tim Olson) (09/29/89)
In article <8862@etana.tut.fi> pl@etana.tut.fi (Lehtinen Pertti) writes: | From article <12070@cit-vax.Caltech.Edu>, by wen-king@cit-vax.Caltech.Edu (King Su): | > | > #define bool(a) (!!(a)) | > | > Then just use bool(X) whenever you wanted to use (bool)X. | > | | Then suddenly just behind the corner cames C-compiler from | ACME-corporation and realizes '!!a' -> negation of negation is | same as original -> we can optimize it away. | | Nice, isn't it. And too real too. And wrong, too. Do you know of a compiler that does this in the general case? -- Tim Olson Advanced Micro Devices (tim@amd.com)
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/29/89)
In article <8862@etana.tut.fi> pl@etana.tut.fi (Lehtinen Pertti) writes:
- Then suddenly just behind the corner cames C-compiler from
- ACME-corporation and realizes '!!a' -> negation of negation is
- same as original -> we can optimize it away.
The point is, it isn't a no-op.
If ACME delivers a non-conforming implementation,
you should hold them to your specification that requires Standard
conformance.
diamond@csl.sony.co.jp (Norman Diamond) (09/29/89)
From article <12070@cit-vax.Caltech.Edu>, by wen-king@cit-vax.Caltech.Edu (King Su): >> #define bool(a) (!!(a)) >> Then just use bool(X) whenever you wanted to use (bool)X. In article <8862@etana.tut.fi> pl@etana.tut.fi (Lehtinen Pertti) writes: > Then suddenly just behind the corner comes C-compiler from > ACME-corporation and realizes '!!a' -> negation of negation is > same as original -> we can optimize it away. Actually no. If the optimizer reduces this to a no-op without knowing that "a" must already be 0 or 1, then the optimizer is broken. "!" was required to produce a result of 0 or 1 even before K&R-1. -- Norman Diamond, Sony Corporation (diamond@ws.sony.junet) The above opinions are inherited by your machine's init process (pid 1), after being disowned and orphaned. However, if you see this at Waterloo or Anterior, then their administrators must have approved of these opinions.
condict@cs.vu.nl (Michael Condict) (09/29/89)
In article <12070@cit-vax.Caltech.Edu> wen-king@cit-vax.UUCP (Wen-King Su) writes: >In article <393@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes: >>The biggest advantage of a built-in boolean type would be that casts TO it ><would test for zero/non-zero rather than just trucating the high-order bits >>if sizeof(source) is bigger than sizeof(bool). Also, . . . > >Why not just do: > >#define bool(a) (!!(a)) > >Then just use bool(X) whenever you wanted to use (bool)X. > Because neither lint nor the C compiler will help you find the places where you forgot to use bool(X). Presumably, ints would be cast to the proposed Boolean type automatically, as needed. Or the two types would be incompatible and require an explicit cast to avoid an error message (except when ints are used in the bool-expr of a while loop or if statement). One of the biggest problems with C, compared to strongly typed languages like Pascal, is that it doesn't help you enough in finding type mismatch errors. ANSI C does not solve this problem completely, although its function prototypes at least allow compilers to do their weak type checking across function boundaries, as well as within a single compilation unit. Unfortunately the only cases for which the weak type checking produces error messages is when pointers and numeric types, or two different pointer types, are mixed. Consider the case where you have a function that expects a float, an int and a char. In most cases, you the programmer consider these to be different, incompatible types, and would consider it an error to pass a character constant in the place where the float is expected. This would almost cer- tainly indicate that the caller got the order of the parameters wrong. C, on the other hand, happily (and quietly) converts the character, which is a numeric type, to a float, in the presence of a prototype. In the absence of a prototype, lint will complain about the mismatch of the char and float, but will not complain if you get the order of the char and int parameter wrong. The issue is this: is a programming language always more powerful when it accepts a given construct, rather than rejecting it with an error message? Or is it sometimes weaker? Opinions differ when specific constructs are discussed, but I doubt if anyone would want to go back to the bad old days when integers and pointers were compatible types and could be interchanged freely. Michael Condict condict@cs.vu.nl Vrije University
bright@Data-IO.COM (Walter Bright) (09/30/89)
In article <8862@etana.tut.fi> pl@etana.tut.fi (Lehtinen Pertti) writes:
<From article <12070@cit-vax.Caltech.Edu>, by wen-king@cit-vax.Caltech.Edu (King Su):
<< #define bool(a) (!!(a))
< Then suddenly just behind the corner cames C-compiler from
< ACME-corporation and realizes '!!a' -< negation of negation is
< same as original -< we can optimize it away.
If a compiler thought that (!!a) == (a), then it is a compiler bug.
< Nice, isn't it. And too real too.
If you run up against such wretchedness, you can do this:
#if ACME_C
#define bool(a) ((a) != 0) /* if desperate try ((a)?1:0) */
#else
#define bool(a) (!!(a))
#endif
I have a copy of K&R which I believe is a first printing. It *clearly*
states that ! is to return 1 or 0. Not -1. Not implementation defined.
Using ! is portable. If it doesn't work with your C, treat it like any
other compiler bug.
If anyone knows of a *current* C compiler that has a problem with this,
please email me. I'm curious!