Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!mcvax!botter!tjalk!rblieva From: rblieva@cs.vu.nl (Roemer b Lievaart) Newsgroups: comp.lang.c Subject: Re: Writing readable code Message-ID: <849@tjalk.cs.vu.nl> Date: Wed, 1-Jul-87 18:55:35 EDT Article-I.D.: tjalk.849 Posted: Wed Jul 1 18:55:35 1987 Date-Received: Fri, 3-Jul-87 05:07:48 EDT References: <13008@topaz.rutgers.edu> <1941@zeus.TEK.COM> Reply-To: rblieva@cs.vu.nl (Roemer B. Lievaart) Organization: VU Informatica, Amsterdam Lines: 185 Keywords: Who's obfuscated? Excuse: me foreigner. Me not can very good english. I know I won the "obfuscated C code contest", but I guess I didn't deserve it, when I read these articles! :-)))) No, serious, I just joined in (and will join out soon, vacation), but I can't help thinking I must put it all straight. Probably I missed most of the point of these articles, but I didn't miss the blunders spread around! Flame on! In article <1941@zeus.TEK.COM> dant@tekla.UUCP (Dan Tilque) writes: >Ron Natalie writes: > >> I also wonder about people who define TRUE to be any >>thing, since it leads to things like >> if( bool == TRUE ) >>which is different than >> if(!bool) Of course it's different. If bool can only be 0 or TRUE, "bool == TRUE" is exactly the opposite of " ! bool ", isn't it? Unless TRUE is defined as 0, which is a great idea for the next year's obf. C contest. > >I thought that TRUE and FALSE should be: > >#define FALSE 0 >#define TRUE !FALSE > >With these #defines the above two statements are equivalent. Somebody is being very stupid - the two of you or me... who can tell? >> >>Generally, I use !p when I'm dealing with things that are supposed >>boolean values like >> >> if(!isdigit(c)) > >It's often easy to miss a single character (especially one that doesn't >stand out like the "!") when quickly scanning code. I have no problems with that as I mostly write if ( ! isdigit(c) ) Stands out enough for me. > > if (isdigit(c) == TRUE) > >will compile to the same object code on almost every compiler and is easier >to grasp immediately. The fact that it's positive logic also makes it >easier. > Sigh. I really wouldn't define TRUE as 0. However if (isdigit(c) == 0) is a good idea, I would say. But! To avoid some misunderstandings: isdigit(), isalpha(), etc. do NOT just return FALSE or "TRUE" (1)!!! Watch the next program and its output: ----- #include #define FALSE 0 #define TRUE (!FALSE) main() { printf("%d %d %d\n", isalpha('a'), isupper('Z'), isdigit('0') ) ; if ( isalpha('a') ) puts("yes") ; else puts("no") ; if ( isalpha('a') == TRUE ) puts("yes") ; else puts("no") ; } ------ output: ------ 2 1 4 yes no -------- Do you get it? isalpha('a') is not true! $%&#?! It's not true, it's 2. This may look sickening to some, but if you think so, learn Pascal. And so I come to another article (too bad rn lets you 'F'ollowup only one article at a time) : In article jas@rtech.UUCP (Jim Shankland) writes: > In article <6034@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes: > This is, indeed, a silly debate, and I'm sure we will never come to > consensus; but years of moving other people's C code to dozens of > different machines has absolutely convinced me that being able to say: > > if (integer-or-pointer-valued-expr) > > is an error-prone misfeature, and that we'd all be better off programming > as though it didn't exist. > -- > Jim Shankland I get your point Jim, but I must say it's rather Pascal-minded (or whatever other languages that are boolean-freaking). In C it doesn't always work that perfect, as I illustrated above. So what do you do? You adapt yourself to C (instead of all those people who want to adapt C or the other C-programmers) and you learn to work with things like if ( strlen( name ) ) ... and get used to it, so that it is just as clear for you as is if ( strlen( name ) != 0 ) or even "better" if ( strlen( name ) > 0 ) It is for me now. It can be for you too. Just as you learn that in Pascal if a then is equivalent to if a = true then you'll have to learn that in C if ( a ) is equivalent to if ( a != 0 ) [ new subject: ] However, I must say I'm very against using '0' instead of NULL. I know its the same, but I want to know whether someone is working with integers or pointers. (Yes I know, maybe I have too learn that, too, just as the thing I described above, but I don't think so. Because the example above really can give wrong results, as indicated, and a strict 0 / NULL discrimination only makes your programs clearer, without side-effects.) And so I come to a last point: Our lint complains about: main(){ bar( NULL ) ; } bar ( foo ) char *foo ; { ... } I know that indeed there better should be a complaint in the second case, but it should be like: "the compiler doesn't know that the parameter 0 is a pointer; possible alignment problem" or something like that. Instead lint says: "bar, arg. 1 used inconsistently ..." Which is not true. I didn't use the argument inconsistently, I passed a NULL-pointer which is a correct pointer. The problem is that the compiler doesn't KNOW it's a pointer (it's just the integer 0), as long as I won't put "(char *)" in front of it. Okay, I can get over this. But how about this: char *strings[] = { "one", "two", "three", NULL } ; This won't pass our compiler. Which is dumb, as the compiler knows pointers to characters are coming up, finds a zero, and does not conclude it should be a NULL-pointer. But is does conclude so in: char *onestring = NULL ; Strange, I would say. How do other compilers react to this? Anyway, that's enough for today. It's almost bedtime, let's not dream about null-pointers, let's dream about birds, music, love and all those other things some programmers sometimes forget... :-) (And I may be well one of those addicts!) Let's live, Roemer B. Lievaart, Amsterdam. Disclaimer: The opinions expressed by the VU are not mine.