jreuter@cincy.UUCP (Jim Reuter) (12/28/83)
I agree with almost everything Steve Summit (azure!stevesu) has to
say about typedefs, readability, and other things, but I strongly
disagree with the following statement:
...
I once had points taken off on a programming assignment for
writing something like
if(a == b) return(TRUE);
else return(FALSE);
The grader said I should have "more succinctly" said
return(a == b);
I realize now that he was wrong, and I wish I'd realized it then,
and called him on it. He was obviously a fully indoctrinated
member of the "hacks are beautiful" school. Those two fragments
do do the same thing, and this is a case where the second one
might even generate slightly more efficient code. But I have to
look at something like "return(a == b)" twice or even three times
to convince myself that it's identical to what I conceptualize as
"if a equals b it's true, otherwise it's not." Why make things
difficult? I know the idiom, and it still gets in my way.
...
I think his confusion may arise from the fact that in C, boolean values
are integers. In some programming languages, booleans are completely
separate from integer types, and one can declare a function of boolean
type that will return TRUE or FALSE as the result of a boolean
(comparison) operation. In fact, this is just what boolean operators
are.
Perhaps if he used the much discussed typedef, and wrote
typedef int BOOL;
BOOL
somefunc( a, b )
int a,b;
{
return( a == B );
}
things would seem clearer. I disagree with his statement that his
first example is clearer, and I can show several examples of
similar constructs which are definitely NOT clearer:
c = a > b ? a : b;
is worse than
#define max(a,b) (a > b ? a : b)
c = max( a, b );
or perhaps
if (i == 5)
i = 6;
if (i == 4)
i = 5;
if (i == 3)
i = 4;
if (i == 2)
i = 3;
if (i == 1)
i = 2;
is far worse than
i = i + 1;
or even
i++;
This last example I saw three years ago in an article about some
programming atrocities that real, practicing, "professional programmers"
were commiting. It was written by a manager of a programming staff.
I realize it is a bit extreme, but it is of the same style.
ucbesvax.turner@ucbcad.UUCP (12/30/83)
#R:cincy:-116500:ucbesvax:23100004:000:646 ucbesvax!turner Dec 30 03:26:00 1983 Re: returning crafty boolean expressions typedef int BOOL; /* ?! */ That's not what I do! I have (in ~turner/include/macros.h): typedef enum { FALSE, TRUE } bool; With this bool-type, the following causes a type-clash on return value warning: bool yes( ) { return getchar( ) == 'y'; } I would have to (and am willing to) say, instead: bool yes( ) { if (getchar( ) == 'y') return TRUE; else return FALSE; } If this grosses you out, you probably wouldn't want to look at any of the rest of my code. I like weak languages to be strongly typed. --- Michael Turner (ucbvax!ucbesvax.turner)
tim@unc.UUCP (12/31/83)
Indeed, you could make a case that the conditional form if ( a == b ) return( TRUE ); else return( FALSE ); is the hacky one, and not return( a == b ); The idea of a Boolean expression is a part of all procedural languages I'm familiar with, including C, Pascal, and so on. If the programmer can't understand the idea of a Boolean expression yielding a Boolean value, that's his blind spot, and it will lead to inferior code. -- Tim Maroney, University of North Carolina at Chapel Hill duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)
keesan@bbncca.ARPA (Morris Keesan) (01/03/84)
----------------------------------- >ucbesvax!turner Dec 30 03:26:00 1983 >Re: returning crafty boolean expressions > typedef int BOOL; /* ?! */ >That's not what I do! I have (in ~turner/include/macros.h): > typedef enum { FALSE, TRUE } bool; >With this bool-type, the following causes a type-clash on return value warning: > bool yes( ) > { > return getchar( ) == 'y'; > } >I would have to (and am willing to) say, instead: > bool yes( ) > { > if (getchar( ) == 'y') > return TRUE; > else > return FALSE; > } >>>>>>>>> I question the utility of a 'bool' type which generates type-clashes with boolean expressions. However, if you insist on using it, do you object to return( (bool)(getchar() == 'y') ); ? This avoids the type-clash warning, and is guaranteed to work. Saying if( getchar() == 'y' ) return TRUE; else return FALSE; is only one step away from if( (getchar() == 'y') == TRUE ) return TRUE; else return FALSE; and equally silly. The whole point of boolean types/values is that they reflect the values which can be held by boolean expressions. -- Morris M. Keesan {decvax,linus,wjh12}!bbncca!keesan keesan @ BBN-UNIX.ARPA
gwyn%brl-vld@sri-unix.UUCP (01/03/84)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> I think one's programming style is improved if he carefully maintains the distinction between boolean data and integer data, even though the C language does not. Examples: if ( p != NULL ) fputs( p, stdout ); rather than if ( p ) fputs( p, stdout ); while ( *p != '\0' ) putchar( *p++ ); rather than while ( *p ) putchar( *p++ ); Although the above alternatives lead to identical machine code and are not obviously superior taken out of context, they say precisely what is intended without requiring the reader to remember C-specific language peculiarities. I find that careful attention to data typing, of which boolean-vs-integer is a small part, contributes to error-free coding.
gwyn%brl-vld@sri-unix.UUCP (01/04/84)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> You have discovered why one should NOT typedef "boolean" as an enum.
ajs@hpfcla.UUCP (01/04/84)
#R:cincy:-116500:hpfcla:43800001:000:715 hpfcla!ajs Jan 2 17:50:00 1984 I also prefer "return (a == b);" to a less-concise form. But that's not what bugs me. What I'd like to know is, why did the authors of the articles on the subject write "return( a == b );" as they did? In English we don't( usually )use parentheses that way, and English is what most of us are used to reading. It seems commonsensical to me to use lexical forms when programming that most approximate our natural language. Why do most programmers seem to behave as if they disagreed? (See my recent flames about quoting and commenting styles...) Alan Silverstein, Hewlett-Packard Fort Collins Systems Division, Colorado {ihnp4 | hplabs}!hpfcla!ajs, 303-226-3800 x3053, N 40 31'31" W 105 00'43"
chris@umcp-cs.UUCP (01/05/84)
Re: From: keesan@bbncca.UUCP [ Re: ... typedef enum { FALSE, TRUE } bool; ... ] I question the utility of a 'bool' type which generates type-clashes with boolean expressions. However, if you insist on using it, do you object to return( (bool)(getchar() == 'y') ); ? This avoids the type-clash warning, and is guaranteed to work. Unfortunately it's not *guaranteed* to work, unless you use typedef enum { FALSE = 0, TRUE = 1 } bool; to ensure that (bool) 0 == FALSE and (bool) 1 == TRUE. Otherwise the result of a boolean expression may be neither FALSE nor TRUE! Personally I just use integers as boolean-variables. (As if anyone cares.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris.umcp-cs@CSNet-Relay
ucbesvax.turner@ucbcad.UUCP (01/05/84)
#R:cincy:-116500:ucbesvax:23100006:000:401 ucbesvax!turner Jan 4 03:50:00 1984 Could we move this to net.lang? It's certainly no sillier than what's going on there now--it even relates, tangentially. The example could serve as flame-thrower fuel for both sides, if the discussion so far is any indication. net.unix is supposed to be unix-consultant of last resort, not a net.towering.inferno. Sorry to be flaming (and metaflaming). --- Michael Turner (ucbvax!ucbesvax.turner)
ron%brl-vgr@sri-unix.UUCP (01/05/84)
From: Ron Natalie <ron@brl-vgr> @"#@%`*@ pinko computer science freaks... Every hacker knows there is really only one data type--integer (in C "int"). Booleans are just wedged in there. Real Fortran programmers have been rounding integers by adding results of ".AND." to their INTEGER variables. C just legitimizes this. No real programmer uses floating point, too ineffecient (he does this even on machines like HEP which compute floating point faster than they do integers). He just approximates by using fixed integers again. Characters are just integers made smaller. Again, the real programmer null-terminates his strings with a "0" not a "'\0'" or "NULL". Everyone knows that space is 40(base 8) in ASCII and 40(base 16) in EBCDIC and ASCII characters less than 32 are no printing. Don't forget that character constants in C are integers! :->
thomas@utah-gr.UUCP (Spencer W. Thomas) (01/05/84)
Not to beat on an old subject too much (and, please, let's not start yet another discussion on this matter), but the parentheses on the return statement have not been required since Unix V6. So, howcome everybody keeps using them? Is this just another example of "programmer superstition?". What gives? The question "why use the style `return( a == b );'?" was raised. Well, I think that this is in analogy to a function call, where the parentheses are part of the function call syntax, not the arguments. E.g., I would write `f( a )' in preference to `f (a)'. Now, in the return statement, the parentheses are NOT a part of the syntax, so if you are going to use them, you should probably write `return (a == b);' to remain consistent. But, `return a == b;' will do just as well. =Spencer "I always remove parens from returns"
gwyn%brl-vld@sri-unix.UUCP (01/06/84)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> Not everyone on the Info-UNIX mailing list has access to net.lang. Unless you want to volunteer to gateway it to the ARPAnet?
tim@unc.UUCP (01/09/84)
Note for Michael Turner: "Boolean" in C happens to be represented by the same type as integers. This does not mean that there is no explicit concept of a Boolean data type or expression. There is a large set of operators which manipulate Boolean data; there are concepts in which only Boolean data is permissible as the value of an expression. The idea is there; it is simply not made into a data type with its own declaration syntax. -- Tim Maroney, University of North Carolina at Chapel Hill duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)
ucbesvax.turner@ucbcad.UUCP (01/09/84)
#R:cincy:-116500:ucbesvax:23100005:000:853 ucbesvax!turner Jan 2 19:20:00 1984 > /***** ucbesvax:net.unix / unc!UUCP / 8:30 am Dec 31, 1983*/ > The idea of a Boolean expression is a part of all procedural languages > I'm familiar with, including C, Pascal, and so on. If the programmer > can't understand the idea of a Boolean expression yielding a Boolean > value, that's his blind spot, and it will lead to inferior code. > -- > Tim Maroney, University of North Carolina at Chapel Hill I wouldn't mind if "a==b" was a Boolean expression--I would be quite happy with "return (a==b)" if it was really Boolean. But in C, it's not. It's an integer-valued expression. See K&R, if you don't believe me--there is no intrinsic Boolean type. If the compiler can't understand the idea of a Boolean expression, that's its blind spot. It does lead to inferior code, at that. --- Michael Turner (ucbvax!ucbesvax.turner)
ajs@hpfcla.UUCP (01/09/84)
#R:cincy:-116500:hpfcla:43800003:000:1514 hpfcla!ajs Jan 7 16:34:00 1984 Sigh... I'm all for logical arguments, when they apply. (I'm all for posting to the right group, too, but you have to wade into battle where the action is.) Anyway, I'm convinced that there are few cases where purely logical arguments, without reference to human nature, result in software that IN PRACTICE is easier to maintain than otherwise. For example, someone stated that function parentheses are syntactically part of the function call, not the arguments, so you shouldn't leave a blank between the name and the left paren. Sounds good in principle, but which of these is easier to read? myfunc(arg1, arg2, arg3); /* barble one widget */ myfunc (arg1, arg2, arg3); /* barble one widget */ Like many people, I find that the left paren gets lost in the first case (everything up to the comma looks like one token). I suppose that: myfunc( arg1, arg2, arg3 ); /* barble it again */ might solve that problem if it weren't so opposite of English (it hides the function call and highlights the arguments). For similar reasons I like parens in returns, even if they are not required. They emphasize the "return" and enclose the value. Nevermind, it's hopeless, this is a religious issue! Just be consistent, whatever you do, and take pity on those who will support your code after you ascend to greater things. Alan Silverstein, Hewlett-Packard Fort Collins Systems Division, Colorado {ihnp4 | hplabs}!hpfcla!ajs, 303-226-3800 x3053, N 40 31'31" W 105 00'43"
tim@unc.UUCP (01/09/84)
Alan Silverstein is correct in criticizing the use of white space in my "return( a == b );". I should have said "return a == b;", which is the clearest way to do it in C. -- Tim Maroney, University of North Carolina at Chapel Hill duke!unc!tim (USENET), tim.unc@csnet-relay (ARPA)
turner%ucbesvax%berkeley@sri-unix.UUCP (01/10/84)
From: Michael Turner <turner%ucbesvax@berkeley> Thank you for your opinion. Offhand, I would compute its value as (0 ? 0 : 0) != (0 <= 0 ? (0 >= 0) : 1) -mike
alan@allegra.UUCP (Alan S. Driscoll) (01/14/84)
From: chris@umcp-cs.UUCP Newsgroups: net.unix Subject: Re: typedefs, etc. - (nf) Re: From: keesan@bbncca.UUCP [ Re: ... typedef enum { FALSE, TRUE } bool; ... ] I question the utility of a 'bool' type which generates type-clashes with boolean expressions. However, if you insist on using it, do you object to return( (bool)(getchar() == 'y') ); ? This avoids the type-clash warning, and is guaranteed to work. Unfortunately it's not *guaranteed* to work, unless you use typedef enum { FALSE = 0, TRUE = 1 } bool; to ensure that (bool) 0 == FALSE and (bool) 1 == TRUE. Otherwise the result of a boolean expression may be neither FALSE nor TRUE! You're wrong. In fact, typedef enum { FALSE, TRUE } bool; is guaranteed to do the right thing. The C Reference Manual (September, 1980) states The identifiers in an enum-list are declared as constants, and may appear wherever constants are required. If no enumerators with = appear, then the values of the corresponding constants begin at 0 and increase by 1 as the declaration is read from left to right. An enumerator with = gives the associated indentifier the value indicated; subsequent identifiers continue the progression from the assigned value. So, FALSE will be given the value 0 and TRUE the value 1 because of their *positions* in the declaration. It amazes me how much misinformation appears on the net. Alan S. Driscoll AT&T Bell Laboratories
obrien%rand-unix@sri-unix.UUCP (01/15/84)
Unfortunately there's a problem with the 4.1BSD VAX compiler in that "enum"s don't do the right thing. They're really treated as a separate data type and give type clashes. This may have been fixed in other compilers. In fact in our compiler they can't even be ordinally compared; you can only test for equality. We're thinking of fixing this.
ajs@hpfcla.UUCP (01/22/84)
#R:cincy:-116500:hpfcla:43800004:000:1090 hpfcla!ajs Jan 14 18:24:00 1984 Tim Maroney's statement that "<whatever> is the clearest way to do it in C" cannot go unchallenged. If there is one thing I have learned by now, it is that there are no absolutes, at least not in this business. Things only seem absolute to people because of their personal perspectives. "Absolutes" are just things almost everyone agrees on. So, you do it your way, I'll do it my way, and if we happen to work on each other's code and don't like it, we can curse each other out publicly, privately, or under our breaths, and maybe that social interaction will influence us in ways that bring us more toward the "accepted standard", and maybe not, because that's how it has always really worked anyway; <flame off>. Alan "I finally got to flame at Tim" Silverstein PS: I reserve to right to make seemingly inconsistent absolutist arguments in the future, because assertiveness is part of the game. PPS: Any cretin (and most other people) can see that "return (a == b);" is clearer than "return a == b;", so there, nyaa, nyaa. :-)