Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Esoteric definitions of TRUE and FALSE

70 views
Skip to first unread message

Noob

unread,
Mar 4, 2011, 9:30:57 AM3/4/11
to
Hello,

I've come across a library which defines TRUE and FALSE thus.

/* BOOL type constant values */
#ifndef TRUE
#define TRUE (1 == 1)
#endif
#ifndef FALSE
#define FALSE (!TRUE)
#endif

Do you know why one would do that, instead of the more
straight-forward (IMO)

#define FALSE 0
#define TRUE 1

or, perhaps,

#define FALSE 0
#define TRUE (!FALSE)

(Given that !0 evaluates to 1.)

??

Regards.

pete

unread,
Mar 4, 2011, 9:56:23 AM3/4/11
to

This doesn't exactly answer your question, but:

My preference is to regard false as being equal to zero,
and to consider true as meaning not equal to zero.
Which is to say that for comparison purposes
I would only ever use the FALSE macro.

<stdbool.h> is one of those C99isms, which I don't like.

--
pete

copx

unread,
Mar 4, 2011, 10:03:16 AM3/4/11
to

"Noob" wrote in message news:ikqt2o$a7i$1...@speranza.aioe.org...

Hello,

I've come across a library which defines TRUE and FALSE thus.

/* BOOL type constant values */
>#ifndef TRUE
> #define TRUE (1 == 1)
>#endif
>#ifndef FALSE
> #define FALSE (!TRUE)
>#endif
>
>Do you know why one would do that,

Forward compatibility. The author obviously expected the ISO C
committee to change C's fundamental boolean values ;)
Seriously, I think the author was just bored, so he chose an
unusual solution to entertain himself.


Keith Thompson

unread,
Mar 4, 2011, 11:02:01 AM3/4/11
to

There is no good reason to do that.

See section 9 of the comp.lang.c FAQ, <http://c-faq.com/>.

In the absence of <stdbool.h>, my favorite form is

typedef enum { false, true } bool;

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson

unread,
Mar 4, 2011, 11:04:42 AM3/4/11
to
pete <pfi...@mindspring.com> writes:
[...]

> My preference is to regard false as being equal to zero,
> and to consider true as meaning not equal to zero.
> Which is to say that for comparison purposes
> I would only ever use the FALSE macro.

Why would you use either TRUE or FALSE for comparison?

(cond == FALSE) is better written as (!cond)
(cond == TRUE) is better written as (cond)

> <stdbool.h> is one of those C99isms, which I don't like.

De gustibus non carborundum, or something like that.

Ben Pfaff

unread,
Mar 4, 2011, 12:37:32 PM3/4/11
to
Noob <ro...@127.0.0.1> writes:

> /* BOOL type constant values */
> #ifndef TRUE
> #define TRUE (1 == 1)
> #endif
> #ifndef FALSE
> #define FALSE (!TRUE)
> #endif
>

> Do you know why one would do that [...]

I think that some people think it is clever. I thought it was
clever, too, the first time I saw it (perhaps 20 years ago), but
I no longer feel that way.
--
Ben Pfaff
http://benpfaff.org

Kenneth Brody

unread,
Mar 4, 2011, 3:57:23 PM3/4/11
to

I used C compilers in K&R1 (ie: pre-ANSI) days, where some systems would
evaluate the expression "1==1" as negative 1.

That said, while I might use TRUE or FALSE in an assignment (or "return")
statement, I would never use them in any comparison operation, as any
non-zero value is "true".

--
Kenneth Brody

Ben Pfaff

unread,
Mar 4, 2011, 4:31:36 PM3/4/11
to
Kenneth Brody <kenb...@spamcop.net> writes:

> I used C compilers in K&R1 (ie: pre-ANSI) days, where some systems
> would evaluate the expression "1==1" as negative 1.

Even K&R1 says (p. 189) that relational operators "all yield 0 if
the specified relation is false and 1 if it is true." It also
says (p. 190) that the equality operators are "exactly analogous
to the relational operators except for their lower precedence."

It seems that the implementation that you worked with was not
very carefully done.

Morris Keesan

unread,
Mar 4, 2011, 5:32:41 PM3/4/11
to
On Fri, 04 Mar 2011 09:30:57 -0500, Noob <ro...@127.0.0.1> wrote:

... (why define TRUE and FALSE as other than 1 and 0?) ...

As others have said, they thought they were being clever.
Either that, or they didn't understand C, or they were afraid that their
compiler implementers didn't understand C.

Personally, I never liked those macros, and I find them over-used.
I'm currently a teaching assistant for a university course which uses C,
and in the course of grading some homework, I've just been ranting to one
of my students about constructs like

if (some_boolean_expression)
return TRUE;
else
return FALSE;

which irritates me to an unreasonable extent, because it's just a more
verbose way of writing
return (some_boolean_expression)

I've also seen expressions like

(x == y) ? TRUE : FALSE

which, inductively, I often feel like re-writing as

((x == y) ? TRUE : FALSE) ? TRUE : FALSE

--
Morris Keesan -- mke...@post.harvard.edu

Ben Pfaff

unread,
Mar 4, 2011, 5:58:14 PM3/4/11
to
"Morris Keesan" <mke...@post.harvard.edu> writes:

> I've also seen expressions like
>
> (x == y) ? TRUE : FALSE
>
> which, inductively, I often feel like re-writing as
>
> ((x == y) ? TRUE : FALSE) ? TRUE : FALSE

I like it better without the confusingly redundant parentheses:
x == y ? TRUE : FALSE ? TRUE : FALSE ? TRUE : FALSE
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

Michael Angelo Ravera

unread,
Mar 4, 2011, 6:42:16 PM3/4/11
to

I don't happen to agree with it, but the reason for defining the TRUE
macro as (1==1) would be that you can be assured that the compiler
will evaluate (1==1) to true and, if you ever need to compare that
value (some implementations might give -1 for the result), you will
always get the right value.

However, the only proper "comparison" of proper boolean values is for
logical equivalence, logical implication and the like. In the
abstract, boolean values should not be compared, but tested.

"if (boolean value != 0") is an obfuscation of "if (boolean_value)"

"if (boolean_value == 1)" might not even produce the desired results
depending upon your implementation.

Ben Pfaff

unread,
Mar 4, 2011, 6:55:44 PM3/4/11
to
Michael Angelo Ravera <mara...@prodigy.net> writes:

> I don't happen to agree with it, but the reason for defining the TRUE
> macro as (1==1) would be that you can be assured that the compiler
> will evaluate (1==1) to true and, if you ever need to compare that
> value (some implementations might give -1 for the result), you will
> always get the right value.

No implementation of standard C will give -1 for the result of 1==1.

Kenny McCormack

unread,
Mar 4, 2011, 7:34:28 PM3/4/11
to
In article <87zkpae...@blp.benpfaff.org>,

Hmmm.. I just wrote one last night that did.

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...

John Bode

unread,
Mar 4, 2011, 8:09:05 PM3/4/11
to
On Friday, March 4, 2011 8:30:57 AM UTC-6, Noob wrote:
> Hello,
>
> I've come across a library which defines TRUE and FALSE thus.
>
> /* BOOL type constant values */
> #ifndef TRUE
> #define TRUE (1 == 1)
> #endif
> #ifndef FALSE
> #define FALSE (!TRUE)
> #endif
>
> Do you know why one would do that

[snip]

The most charitable explanation is that they are unfamiliar with how booleans work in C.

The danger in writing macros for TRUE and FALSE is that, on rare occasions, people will manage to misspell 0 or 1 (or the expression that's supposed to evaluate to 0 or 1). I spent an afternoon chasing my tail because someone dropped a header where TRUE==FALSE.

Not coincidentally, that was the day I stopped using symbolic constants for Boolean values.

Keith Thompson

unread,
Mar 4, 2011, 8:34:37 PM3/4/11
to
John Bode <jfbod...@gmail.com> writes:
> On Friday, March 4, 2011 8:30:57 AM UTC-6, Noob wrote:
>> Hello,
>>
>> I've come across a library which defines TRUE and FALSE thus.
>>
>> /* BOOL type constant values */
>> #ifndef TRUE
>> #define TRUE (1 == 1)
>> #endif
>> #ifndef FALSE
>> #define FALSE (!TRUE)
>> #endif
>>
>> Do you know why one would do that
>
> [snip]
>
> The most charitable explanation is that they are unfamiliar with
> how booleans work in C.
>
> The danger in writing macros for TRUE and FALSE is that, on rare
> occasions, people will manage to misspell 0 or 1 (or the expression
> that's supposed to evaluate to 0 or 1). I spent an afternoon
> chasing my tail because someone dropped a header where TRUE==FALSE.

Did any other code break when you fixed the definitions?

> Not coincidentally, that was the day I stopped using symbolic
> constants for Boolean values.

--

Morris Keesan

unread,
Mar 4, 2011, 9:36:42 PM3/4/11
to
On Fri, 04 Mar 2011 20:09:05 -0500, John Bode <jfbod...@gmail.com> wrote:

> The danger in writing macros for TRUE and FALSE is that, on rare
> occasions, people will manage to misspell 0 or 1 (or the expression
> that's supposed to evaluate to 0 or 1). I spent an afternoon chasing my
> tail because someone dropped a header where TRUE==FALSE.

Here's another one: I've just been looking at some code (which I should
finish grading, instead of wasting my time on Usenet) with the following
two lines:

#define TRUE 1;
#define FALSE 0;

Eric Sosman

unread,
Mar 4, 2011, 10:07:13 PM3/4/11
to
On 3/4/2011 11:02 AM, Keith Thompson wrote:
> [...]

> In the absence of<stdbool.h>, my favorite form is
>
> typedef enum { false, true } bool;

Reading someone else's code, I once encountered

typedef enum { TRUE, FALSE } Boolean;

Any guesses why I was reading the code? There were B-U-U-G-S...

--
Eric Sosman
eso...@ieee-dot-org.invalid

Eric Sosman

unread,
Mar 4, 2011, 10:13:09 PM3/4/11
to

Hmmm. Some plausible uses would actually compile:

...
flag = FALSE;
return TRUE;

A few compilers, though, would complain about "useless statement"
or "unreachable statement," or maybe even "unreachable useless
statement!"

--
Eric Sosman
eso...@ieee-dot-org.invalid

James Kuyper

unread,
Mar 4, 2011, 10:41:13 PM3/4/11
to

Yes. Those definitions have, under certain very implausible
circumstances, one definite advantage. The implausible circumstances
involve a potential reader who
a) understands or can guess that == is the C equality comparison operator
b) understands or can guess that ! is the C logical negation operator
c) is not certain what values C treats as true and false.

Such a reader can verify that these definitions are correct, just by
reading and understanding them, without having to resolve his confusion
on item c.

I wouldn't write my code to target such a peculiar audience - but I've
certainly seen weirder code than that.

--
James Kuyper

Morris Keesan

unread,
Mar 4, 2011, 10:57:51 PM3/4/11
to

ALL of his uses compiled, which is why those defines were still in the
code when the homework was submitted. Fortunately, or perhaps
unfortunately, he only ever used the values in assignment and return
statements, and never in any context like

if (condition)
flag = TRUE;
else

James Dow Allen

unread,
Mar 5, 2011, 4:35:25 AM3/5/11
to
On Mar 5, 10:57 am, "Morris Keesan" <mkee...@post.harvard.edu> wrote:

> ALL of his uses compiled, which is why those defines were still in the
> code when the homework was submitted. Fortunately, or perhaps
> unfortunately, he only ever used the values in assignment and return
> statements, and never in any context like
>
> if (condition)
> flag = TRUE;
> else

In the absence of a preceding *if*, that example has the virtue
of producing a compiler error -- clearly a better outcome than
faulty code that compiles error-free.

As I've reported before, I've seen similar flaws in glibc source,
so your student is in "good" company. :-)

James

Jorgen Grahn

unread,
Mar 5, 2011, 6:09:46 AM3/5/11
to
On Sat, 2011-03-05, Kenny McCormack wrote:
> In article <87zkpae...@blp.benpfaff.org>,
> Ben Pfaff <b...@cs.stanford.edu> wrote:
>>Michael Angelo Ravera <mara...@prodigy.net> writes:
>>
>>> I don't happen to agree with it, but the reason for defining the TRUE
>>> macro as (1==1) would be that you can be assured that the compiler
>>> will evaluate (1==1) to true and, if you ever need to compare that
>>> value (some implementations might give -1 for the result), you will
>>> always get the right value.
>>
>>No implementation of standard C will give -1 for the result of 1==1.
>
> Hmmm.. I just wrote one last night that did.

You mean you wrote here *about* an ancient compiler which did.
But as others replied, that compiler was horribly broken. It shouldn't
affect how people write C code today.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

James Dow Allen

unread,
Mar 5, 2011, 6:47:47 AM3/5/11
to
On Mar 5, 4:35 pm, James Dow Allen <jdallen2...@yahoo.com> wrote:
> On Mar 5, 10:57 am, "Morris Keesan" <mkee...@post.harvard.edu> wrote:
>
> > ALL of his uses compiled, which is why those defines were still in the
> > code when the homework was submitted.  Fortunately, or perhaps
> > unfortunately, he only ever used the values in assignment and return
> > statements, and never in any context like
>
> >    if (condition)
> >        flag = TRUE;
> >    else
>
> In the absence of a preceding *if*, that example has the virtue
> of producing a compiler error -- clearly a better outcome than
> faulty code that compiles error-free.

On reread, what I wrote makes no sense! :-(

Puzzle 1: Is there any error-free program where
replacing ";" with ";;" yields an *error-free*
program with different semantic meaning?

Puzzle 2: Given a macro definition like
#define TRUE 1;
what is the *least-contrived* error-free program where
the extra ";" yields an *error-free* program with
different semantic meaning?

James

Message has been deleted

pete

unread,
Mar 5, 2011, 9:45:24 AM3/5/11
to
Stefan Ram wrote:

>
> Keith Thompson <ks...@mib.org> writes:
> >(cond == TRUE) is better written as (cond)
>
> This is not just »better«, it is they only correct way.
>
> false:
>
> if( isprint( ch )== TRUE )...
>
> correct:
>
> if( isprint( ch )) ...
>
> (»The functions in this subclause return nonzero (true) if
> and only if the value of the argument c conforms to that in
> the description of the function.«)

The following line would work just fine:

if (isprint(ch) != FALSE)

However,

if (isprint(ch))

is actually the way that I would really write that in source code,
because the only meaning of the return value of isprint
is whether or not it compares equal to zero.

For other cases, such as the return value of malloc,
there is more meaning to the return value
besides whether or not it compares equal to zero;
and for that reason I would be more inclined to write

if ((ptr = malloc(sizeof *ptr)) != NULL)

rather than

if (ptr = malloc(sizeof *ptr))

And to answer Keith Thompson's question from upthread,
I am completely disinclined
to write either TRUE or FALSE in source code.
I was only trying to imagine how I would use those macros,
if I were to use them.

--
pete

Ben Bacarisse

unread,
Mar 5, 2011, 9:58:58 AM3/5/11
to
James Dow Allen <jdall...@yahoo.com> writes:
<snip>

> Puzzle 1: Is there any error-free program where
> replacing ";" with ";;" yields an *error-free*
> program with different semantic meaning?

Yes[1].

> Puzzle 2: Given a macro definition like
> #define TRUE 1;
> what is the *least-contrived* error-free program where
> the extra ";" yields an *error-free* program with
> different semantic meaning?

I can see a lot of noise being generated over the measure used for
"contrived" but I can't think of an any entirely normal usage of the
macro that would cause such trouble. However, operators that are both
unary and binary are problematic after semicolons. For example,

int x = TRUE - y;

but Boolean operands are hardly normal for + and -.

[1] Spoiler...

I was going to post an example rot13-ed but the key elements are not
hidden by rot13 in this case:

#include <stdio.h>
#define s(a) #a
int main(void) { puts(s(;)); }

--
Ben.

Ben Pfaff

unread,
Mar 5, 2011, 10:28:58 AM3/5/11
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> On Sat, 2011-03-05, Kenny McCormack wrote:
>> In article <87zkpae...@blp.benpfaff.org>,
>> Ben Pfaff <b...@cs.stanford.edu> wrote:
>>>Michael Angelo Ravera <mara...@prodigy.net> writes:
>>>
>>>> I don't happen to agree with it, but the reason for defining the TRUE
>>>> macro as (1==1) would be that you can be assured that the compiler
>>>> will evaluate (1==1) to true and, if you ever need to compare that
>>>> value (some implementations might give -1 for the result), you will
>>>> always get the right value.
>>>
>>>No implementation of standard C will give -1 for the result of 1==1.
>>
>> Hmmm.. I just wrote one last night that did.
>
> You mean you wrote here *about* an ancient compiler which did.

> But as others replied, that compiler was horribly broken. [...]

It also wasn't standard C.
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton

Keith Thompson

unread,
Mar 5, 2011, 1:07:34 PM3/5/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Keith Thompson <ks...@mib.org> writes:
>>(cond == TRUE) is better written as (cond)
>
> This is not just »better«, it is they only correct way.
>
> false:
>
> if( isprint( ch )== TRUE )...
>
> correct:
>
> if( isprint( ch )) ...
>
> (»The functions in this subclause return nonzero (true) if
> and only if the value of the argument c conforms to that in
> the description of the function.«)

In the case of the is*() functions, yes, comparing their
results to TRUE (or true, or 1, or ...) is semantically incorrect.

But there are plenty of cases where the value of cond is, for
whatever reason, guaranteed by the language to be either 0 or 1.
For example, the equality and relational operators always yield 0
or 1. If (x == y) were to yield 2, most if statements that use it
would still work, but it would indicate a broken compiler.

So given:
int cond = (x == y);
this:
if (cond) ...
and this:
if (cond == TRUE) ...
/* assuming an appropriate definition of TRUE */
are equally correct, but the shorter form is definitely *better*.

(I actually prefer (all else being equal) languages that clearly
distinguish between numeric values and booleans. Neither C99 nor
C++ does so; they both have distinct bool types, but they allow
non-boolean expressions to be used as conditions.)

Keith Thompson

unread,
Mar 5, 2011, 1:11:08 PM3/5/11
to
pete <pfi...@mindspring.com> writes:
[...]

> The following line would work just fine:
>
> if (isprint(ch) != FALSE)
>
> However,
>
> if (isprint(ch))
>
> is actually the way that I would really write that in source code,
> because the only meaning of the return value of isprint
> is whether or not it compares equal to zero.
>
> For other cases, such as the return value of malloc,
> there is more meaning to the return value
> besides whether or not it compares equal to zero;
> and for that reason I would be more inclined to write
>
> if ((ptr = malloc(sizeof *ptr)) != NULL)
>
> rather than
>
> if (ptr = malloc(sizeof *ptr))
>
> And to answer Keith Thompson's question from upthread,
> I am completely disinclined
> to write either TRUE or FALSE in source code.
> I was only trying to imagine how I would use those macros,
> if I were to use them.

TRUE and FALSE or equivalents, IMHO, are quite useful on the RHS of an
assignment. They are not useful in comparisons.

And I agree with you about ptr.

My own strong inclination is that, if an expression only expresses truth
or falsity, it should be treated directly as a boolean and not further
compared to anything else. (It does sometimes make sense to compare
boolean values to each other, but that's fairly rare, and C's semantics
make it risky.) But if an expression expresses something more, as for
"ptr" above, I like to explicitly compare it to something.

Geoff

unread,
Mar 5, 2011, 4:02:43 PM3/5/11
to
On Fri, 04 Mar 2011 08:02:01 -0800, Keith Thompson <ks...@mib.org>
wrote:

>Noob <ro...@127.0.0.1> writes:
>> I've come across a library which defines TRUE and FALSE thus.
>>
>> /* BOOL type constant values */
>> #ifndef TRUE
>> #define TRUE (1 == 1)
>> #endif
>> #ifndef FALSE
>> #define FALSE (!TRUE)
>> #endif
>>
>> Do you know why one would do that, instead of the more
>> straight-forward (IMO)
>>
>> #define FALSE 0
>> #define TRUE 1
>>
>> or, perhaps,
>>
>> #define FALSE 0
>> #define TRUE (!FALSE)
>>
>> (Given that !0 evaluates to 1.)
>

>There is no good reason to do that.
>
>See section 9 of the comp.lang.c FAQ, <http://c-faq.com/>.


>
>In the absence of <stdbool.h>, my favorite form is
>
> typedef enum { false, true } bool;

So what would you recommend in the case of inherited legacy code like
this?

typedef enum bool_n {QFALSE, QTRUE} qboolean;
...

qboolean IsFemale (edict_t *ent)
{
char *info;

if (!ent->client)
return QFALSE;

info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
if (info[0] == 'f' || info[0] == 'F')
return QTRUE;
return QFALSE;
}

Keith Thompson

unread,
Mar 5, 2011, 4:14:13 PM3/5/11
to
Geoff <ge...@invalid.invalid> writes:
> On Fri, 04 Mar 2011 08:02:01 -0800, Keith Thompson <ks...@mib.org>
> wrote:
>>Noob <ro...@127.0.0.1> writes:
>>> I've come across a library which defines TRUE and FALSE thus.
[snip]

>>
>>There is no good reason to do that.
>>
>>See section 9 of the comp.lang.c FAQ, <http://c-faq.com/>.
>>
>>In the absence of <stdbool.h>, my favorite form is
>>
>> typedef enum { false, true } bool;
>
> So what would you recommend in the case of inherited legacy code like
> this?
>
> typedef enum bool_n {QFALSE, QTRUE} qboolean;
> ...
>
> qboolean IsFemale (edict_t *ent)
> {
> char *info;
>
> if (!ent->client)
> return QFALSE;
>
> info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
> if (info[0] == 'f' || info[0] == 'F')
> return QTRUE;
> return QFALSE;
> }

Recommend for what purpose?

If the code works as it is, you're probably better off leaving it alone.

There are a couple of things I would have done differently:

I'd omit the tag "bool_n" on the enum declaration; it's not necessary
and it's probably never used.

Rather than

if (info[0] == 'f' || info[0] == 'F')
return QTRUE;
return QFALSE;

I'd have written:

return (info[0] == 'f' || info[0] == 'F');

(perhaps without the parentheses). Implicit conversion will
reliably convert the int result of the condition to qboolean.

But again, I wouldn't modify existing working code to match my
personal taste, with the risk of introducing new bugs, without a
good enough reason. ("Just because I feel like it" may sometimes
be a good enough reason.)

Eric Sosman

unread,
Mar 5, 2011, 4:58:47 PM3/5/11
to
On 3/5/2011 4:02 PM, Geoff wrote:
> [...]

> So what would you recommend in the case of inherited legacy code like
> this?
>
> typedef enum bool_n {QFALSE, QTRUE} qboolean;
> ...
>
> qboolean IsFemale (edict_t *ent)
> {
> char *info;
>
> if (!ent->client)
> return QFALSE;
>
> info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
> if (info[0] == 'f' || info[0] == 'F')
> return QTRUE;
> return QFALSE;
> }

I'd recommend leaving it alone, unless you have some other
reason to make changes. "If it ain't broke, don't fix it." If
you decide to visit the code for some other reason -- maybe to
add a check for `info == NULL', say -- then you might consider
replacing qboolean at the same time. If you decide to ditch it,
you might do it this way

int IsFemale (const edict_t *ent) {
char *info;
if (ent->client == NULL)
return 0;


info = Info_ValueForKey (ent->client->pers.userinfo,
"skin");

return info != NULL
&& (*info == 'f' || *info == 'F');
}

Note that two of the three explicit uses of a truth constant have
vanished; this kind of simplification is often available when tests
produce manifest Boolean results. You could even get rid of the
one remaining occurrence:

int IsFemale (const edict_t *ent) {
char *info;
return ent->client != NULL
&& (info =
Info_ValueForKey (ent->client->pers.userinfo,
"skin")) != NULL
&& (*info == 'f' || *info == 'F');
}

... but I think this breaches the bounds of good taste.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Spiros Bousbouras

unread,
Mar 5, 2011, 5:44:14 PM3/5/11
to
On Sat, 05 Mar 2011 13:14:13 -0800
Keith Thompson <ks...@mib.org> wrote:
> Geoff <ge...@invalid.invalid> writes:
> > On Fri, 04 Mar 2011 08:02:01 -0800, Keith Thompson <ks...@mib.org>
> > wrote:
> >>Noob <ro...@127.0.0.1> writes:
> >>> I've come across a library which defines TRUE and FALSE thus.
> [snip]
> >>
> >>There is no good reason to do that.
> >>
> >>See section 9 of the comp.lang.c FAQ, <http://c-faq.com/>.
> >>
> >>In the absence of <stdbool.h>, my favorite form is
> >>
> >> typedef enum { false, true } bool;
> >
> > So what would you recommend in the case of inherited legacy code like
> > this?
> >
> > typedef enum bool_n {QFALSE, QTRUE} qboolean;
> > ...
> >
> > qboolean IsFemale (edict_t *ent)
> > {
> > char *info;
> >
> > if (!ent->client)
> > return QFALSE;
> >
> > info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
> > if (info[0] == 'f' || info[0] == 'F')
> > return QTRUE;
> > return QFALSE;
> > }

[...]

> Rather than
>
> if (info[0] == 'f' || info[0] == 'F')
> return QTRUE;
> return QFALSE;
>
> I'd have written:
>
> return (info[0] == 'f' || info[0] == 'F');
>
> (perhaps without the parentheses). Implicit conversion will
> reliably convert the int result of the condition to qboolean.

Nahhh , that's risky. It depends on (info[0] == 'f' || info[0] == 'F')
having the same value as QTRUE. If the value of QTRUE changes for some
weird reason then you have a bug. If one is going to have explicit
constants to denote true and false then one should use them
consistently.

> But again, I wouldn't modify existing working code to match my
> personal taste, with the risk of introducing new bugs, without a
> good enough reason. ("Just because I feel like it" may sometimes
> be a good enough reason.)

--
Erik Naggum: Is there a single problem that would not be solved
by removing people?
Brian Palmer: Underpopulation.

Keith Thompson

unread,
Mar 5, 2011, 5:50:36 PM3/5/11
to
Spiros Bousbouras <spi...@gmail.com> writes:
> On Sat, 05 Mar 2011 13:14:13 -0800
> Keith Thompson <ks...@mib.org> wrote:
>> Geoff <ge...@invalid.invalid> writes:
[...]

>> > typedef enum bool_n {QFALSE, QTRUE} qboolean;
[...]
>> Rather than
>>
>> if (info[0] == 'f' || info[0] == 'F')
>> return QTRUE;
>> return QFALSE;
>>
>> I'd have written:
>>
>> return (info[0] == 'f' || info[0] == 'F');
>>
>> (perhaps without the parentheses). Implicit conversion will
>> reliably convert the int result of the condition to qboolean.
>
> Nahhh , that's risky. It depends on (info[0] == 'f' || info[0] == 'F')
> having the same value as QTRUE. If the value of QTRUE changes for some
> weird reason then you have a bug. If one is going to have explicit
> constants to denote true and false then one should use them
> consistently.

If one is going to have explicit constants for true and false, they had
better have proper values. If they don't, you're going to have bigger
problems anyway.

If, for some reason, you're stuck with something like

typedef enum { xtrue, xfalse } xboolean;

then yes, you need to use xtrue and xfalse explicitly. But I'd
certainly explore the possibility of fixing the definitions so they
don't conflict with C semantics -- or perhaps changing their names
so they don't imply that they mean "true" and "false".

>> But again, I wouldn't modify existing working code to match my
>> personal taste, with the risk of introducing new bugs, without a
>> good enough reason. ("Just because I feel like it" may sometimes
>> be a good enough reason.)

--

Gordon Burditt

unread,
Mar 5, 2011, 8:43:41 PM3/5/11
to
> I've also seen expressions like
>
> (x == y) ? TRUE : FALSE
>
> which, inductively, I often feel like re-writing as
>
> ((x == y) ? TRUE : FALSE) ? TRUE : FALSE

And how would you re-write THAT?

That should probably use a helper macro:

#define istrue(x) ( istrue(x) ? TRUE : FALSE )
(which should be infinitely recursive for stylistic reasons)
which is called as:
istrue(x == y)

For similar reasons, I like:

# define TWUE (!FLASE)
# define FLASE (!TWUE)

luser- -droog

unread,
Mar 6, 2011, 1:37:15 AM3/6/11
to
Keith Thompson wrote:
> Geoff <ge...@invalid.invalid> writes:

> > typedef enum bool_n {QFALSE, QTRUE} qboolean;
...

> I'd omit the tag "bool_n" on the enum declaration; it's not necessary
> and it's probably never used.

Though it probably is useless here, I often find enum tags to be
useful
when inspecting values from the debugger. If I see a 17 that I know
should
be a certain kind of symbol, I can print it with a cast.

gdb> print (enum e_type)17

I don't think this would work without a tag.

John Bode

unread,
Mar 6, 2011, 11:51:23 AM3/6/11
to
On Friday, March 4, 2011 7:34:37 PM UTC-6, Keith Thompson wrote:
> John Bode <jfbod...@gmail.com> writes:

[snip]

> > The danger in writing macros for TRUE and FALSE is that, on rare
> > occasions, people will manage to misspell 0 or 1 (or the expression
> > that's supposed to evaluate to 0 or 1). I spent an afternoon
> > chasing my tail because someone dropped a header where TRUE==FALSE.
>
> Did any other code break when you fixed the definitions?
>

Thankfully, no. But it led me to realize that no two people dealt with Boolean constants in the exact same manner (this was pre-99), so I decided to just dispense with them altogether in my code. I think I've been happier for it.

Geoff

unread,
Mar 6, 2011, 1:51:00 PM3/6/11
to

In this particular case it's there to make browsing in Visual Studio's
class browser easier. Untagged structs and enums get names assigned
like __unnamed_struct_0095_1. It's much easier to find and
double-click a tag to get to the definitions when they all have
sensible names. Anonymous enums can also be hard to find in large
projects so tagging them is helpful in the long run:

enum pmenu_n
{
PMENU_ALIGN_LEFT,
PMENU_ALIGN_CENTER,
PMENU_ALIGN_RIGHT
};

Xcode recognizes both tags and types in its symbol browser but the
search capability is better so it matters less.

Keith Thompson

unread,
Mar 6, 2011, 2:47:40 PM3/6/11
to

Actually, it does; gdb recognizes casts with typedef names.
For example:

(gdb) p (enum bool_n) 1
$1 = QTRUE
(gdb) p (qboolean) 1
$2 = QTRUE

Other tools might have problems with untagged enums, but in any case
there's probably no good reason to use distinct identifiers for the tag
and typedef:

typedef enum qboolean { QFALSE, QTRUE } qboolean;

And even if *that* causes problems for some tools, you can at least use
a consistent naming scheme for tags and typedefs:

typedef enum e_qboolean { QFALSE, QTRUE } qboolean;

Message has been deleted
Message has been deleted

Peter Nilsson

unread,
Mar 6, 2011, 8:18:19 PM3/6/11
to
Keith Thompson <ks...@mib.org> wrote:
> De gustibus non carborundum, or something like that.

<http://en.wikipedia.org/wiki/Illegitimi_non_carborundum>

--
Peter

Keith Thompson

unread,
Mar 6, 2011, 8:39:50 PM3/6/11
to

Yes, that's what the joke referred to.

Noob

unread,
Mar 7, 2011, 4:23:06 AM3/7/11
to
Michael Angelo Ravera wrote:

> On Mar 4, Noob wrote:
>
>> I've come across a library which defines TRUE and FALSE thus.
>>

>> /* BOOL type constant values */
>> #ifndef TRUE
>> #define TRUE (1 == 1)
>> #endif
>> #ifndef FALSE
>> #define FALSE (!TRUE)
>> #endif
>>
>> Do you know why one would do that, instead of the more
>> straight-forward (IMO)
>>
>> #define FALSE 0
>> #define TRUE 1
>>
>> or, perhaps,
>>
>> #define FALSE 0
>> #define TRUE (!FALSE)
>>
>> (Given that !0 evaluates to 1.)
>

> I don't happen to agree with it, but the reason for defining the TRUE
> macro as (1==1) would be that you can be assured that the compiler
> will evaluate (1==1) to true and, if you ever need to compare that
> value (some implementations might give -1 for the result), you will
> always get the right value.

Hmmm... IMHO, working around broken compilers is not a legitimate
reason to write strange-looking code.

3.3.8 Relational operators

Constraints

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./38/ The result
has type int.

3.3.9 Equality operators

Semantics

The == (equal to) and the != (not equal to) operators are analogous
to the relational operators except for their lower precedence./39/

Regards.

James Kuyper

unread,
Mar 7, 2011, 7:44:17 AM3/7/11
to
On 03/07/2011 04:23 AM, Noob wrote:
> Michael Angelo Ravera wrote:
....

>> I don't happen to agree with it, but the reason for defining the TRUE
>> macro as (1==1) would be that you can be assured that the compiler
>> will evaluate (1==1) to true and, if you ever need to compare that
>> value (some implementations might give -1 for the result), you will

Just to emphasize the what you mean by "broken" below: any such
implementations are NOT standard-conforming implementations of C; they
might be implementations of some other, similar language.

>> always get the right value.
>
> Hmmm... IMHO, working around broken compilers is not a legitimate
> reason to write strange-looking code.

Not even if, for some reason, you MUST use such a broken compiler,
perhaps because it's the only one currently available for a given
platform? Writing strange code is often unavoidable.

However, such code should be isolated in platform-specific sections of
the code. I agree that adopting such weird code practices as a general
rule, just because of one broken compiler, is not a good idea.
--
James Kuyper

Eric Sosman

unread,
Mar 7, 2011, 8:11:19 AM3/7/11
to
On 3/7/2011 7:44 AM, James Kuyper wrote:
> On 03/07/2011 04:23 AM, Noob wrote:
>> Michael Angelo Ravera wrote:
> ....
>>> I don't happen to agree with it, but the reason for defining the TRUE
>>> macro as (1==1) would be that you can be assured that the compiler
>>> will evaluate (1==1) to true and, if you ever need to compare that
>>> value (some implementations might give -1 for the result), you will
>
> Just to emphasize the what you mean by "broken" below: any such
> implementations are NOT standard-conforming implementations of C; they
> might be implementations of some other, similar language.

Further to the point, such implementations (if they exist)
are not even "K&R Classic"-conforming. They're not today's C,
and they're not even yesterday's; they're never-never-C.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Kenny McCormack

unread,
Mar 7, 2011, 8:30:13 AM3/7/11
to
In article <slrnin46fo.1...@frailea.sa.invalid>,
Jorgen Grahn <grahn...@snipabacken.se> wrote:
...

>>>No implementation of standard C will give -1 for the result of 1==1.
>>
>> Hmmm.. I just wrote one last night that did.
>
>You mean you wrote here *about* an ancient compiler which did.

Hmmmm. Did I do that as well? I don't remember, but then again, I write so
many brilliant things over the course of time, that I can't be expected to
remember them all.

>But as others replied, that compiler was horribly broken. It shouldn't
>affect how people write C code today.

Anyway, my compiler is available if you're interested.

--
Just for a change of pace, this sig is *not* an obscure reference to
comp.lang.c...

Kenneth Brody

unread,
Mar 7, 2011, 10:16:16 AM3/7/11
to
On 3/5/2011 10:28 AM, Ben Pfaff wrote:
> Jorgen Grahn<grahn...@snipabacken.se> writes:
>
>> On Sat, 2011-03-05, Kenny McCormack wrote:
>>> In article<87zkpae...@blp.benpfaff.org>,
>>> Ben Pfaff<b...@cs.stanford.edu> wrote:
>>>> Michael Angelo Ravera<mara...@prodigy.net> writes:
>>>>
>>>>> I don't happen to agree with it, but the reason for defining the TRUE
>>>>> macro as (1==1) would be that you can be assured that the compiler
>>>>> will evaluate (1==1) to true and, if you ever need to compare that
>>>>> value (some implementations might give -1 for the result), you will
>>>>> always get the right value.
>>>>
>>>> No implementation of standard C will give -1 for the result of 1==1.
>>>
>>> Hmmm.. I just wrote one last night that did.
>>
>> You mean you wrote here *about* an ancient compiler which did.
>> But as others replied, that compiler was horribly broken. [...]
>
> It also wasn't standard C.

Actually, I was the one who wrote about the early-1980's C compilers I used,
where (at least) one of them used -1 rather than 1. I don't know if you
could say there really was a "standard" C at the time.

--
Kenneth Brody

Message has been deleted

pete

unread,
Mar 7, 2011, 10:56:46 AM3/7/11
to
Kenneth Brody wrote:
>
> On 3/5/2011 10:28 AM, Ben Pfaff wrote:
> > Jorgen Grahn<grahn...@snipabacken.se> writes:
> >> On Sat, 2011-03-05, Kenny McCormack wrote:
> >>> In article<87zkpae...@blp.benpfaff.org>,
> >>> Ben Pfaff<b...@cs.stanford.edu> wrote:

> >>>> No implementation of standard C will give -1
> >>>> for the result of 1==1.

> Actually,


> I was the one who wrote about the early-1980's C compilers I used,
> where (at least) one of them used -1 rather than 1.
> I don't know if you
> could say there really was a "standard" C at the time.

The 1978 edition of K&R,
describes the result as being 1.

--
pete

Ben Bacarisse

unread,
Mar 7, 2011, 11:22:46 AM3/7/11
to
Kenneth Brody <kenb...@spamcop.net> writes:

The appendix of K&R was the reference manual for the language before the
ANSI and ISO standards. Any compiler claiming to implement C after 1978
would have to do so in accordance with that definition so I'd consider
the use of -1 to be either a serious bug or an indication that the
compiler was not aiming to implement C, but some variation thereof.

Prior to 1978, anyone implementing C would have to turn to the internal
AT&T "C Reference Manual". That, too, confirms that == etc yield 1 or 0
rather than anything else.

BCPL used -1 for true (well, it used all bits one which is not exactly
the same thing) but even C's predecessor, B, had changed to using 1 and
0 as the result of == and !=.

--
Ben.

Keith Thompson

unread,
Mar 7, 2011, 11:23:06 AM3/7/11
to

Note that K&R1 was published in 1978, and it clearly states that
the relational and equality operators yield 0 or 1.

Going back before K&R1, there are several earlier documents linked
from <http://cm.bell-labs.com/cm/cs/who/dmr/>. The 1974 and 1975
versions of the C Reference Manual both explicitly state that they
yield 0 or 1. For that matter, so does the reference for B, C's
immediate ancestor. (The 1967 BCPL references says that false,
which is a keyword, is represented as all-bits-1.)

There wasn't a formal language standard at the time, but I'd still
say that the compiler was buggy if it claimed to be a C compiler.

Kenneth Brody

unread,
Mar 8, 2011, 10:09:39 AM3/8/11
to
On 3/7/2011 10:46 AM, Stefan Ram wrote:

> Kenneth Brody<kenb...@spamcop.net> writes:
>> Actually, I was the one who wrote about the early-1980's C compilers I used,
>> where (at least) one of them used -1 rather than 1. I don't know if you
>> could say there really was a "standard" C at the time.
>
> Is it possible that you might confuse this with BASIC,
> which was popular these days and used -1 for 1=1?

I know I'm not confusing it with BASIC[1], but it's possible that, being
some 25 years ago, I may simply be confusing it with something else in C
from way back when. Given that even K&R1 says it's 1, there's a good chance
that I'm just misremembering it.


[1] The version of BASIC I had experience with back then was pretty
primitive, even as far as BASIC goes. If you ever read the original release
of "BASIC BASIC", that's basically :-) what it was like.

--
Kenneth Brody

Jonathan Leffler

unread,
Mar 9, 2011, 12:57:43 AM3/9/11
to
On 3/8/11 7:09 AM, Kenneth Brody wrote:
> On 3/7/2011 10:46 AM, Stefan Ram wrote:
>> Kenneth Brody<kenb...@spamcop.net> writes:
>>> Actually, I was the one who wrote about the early-1980's C compilers
>>> I used,
>>> where (at least) one of them used -1 rather than 1. I don't know if you
>>> could say there really was a "standard" C at the time.
>>
>> Is it possible that you might confuse this with BASIC,
>> which was popular these days and used -1 for 1=1?
>
> I know I'm not confusing it with BASIC[1], but it's possible that, being
> some 25 years ago, I may simply be confusing it with something else in C
> from way back when. Given that even K&R1 says it's 1, there's a good
> chance that I'm just misremembering it.


I believe there was a change in the language Forth between 0 and -1 for
true and false to 0 and 1 (or vice versa) at some stage in the now
distant past (1980s, possibly even 1970s).

-=JL=-

Tim Rentsch

unread,
Mar 11, 2011, 3:30:26 PM3/11/11
to
Eric Sosman <eso...@ieee-dot-org.invalid> writes:

> On 3/5/2011 4:02 PM, Geoff wrote:
>> [...]
>> So what would you recommend in the case of inherited legacy code like
>> this?
>>
>> typedef enum bool_n {QFALSE, QTRUE} qboolean;
>> ...
>>
>> qboolean IsFemale (edict_t *ent)
>> {
>> char *info;
>>
>> if (!ent->client)
>> return QFALSE;
>>
>> info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
>> if (info[0] == 'f' || info[0] == 'F')
>> return QTRUE;
>> return QFALSE;
>> }
>

> [...snip first example alternative...]


>
> int IsFemale (const edict_t *ent) {
> char *info;
> return ent->client != NULL
> && (info =
> Info_ValueForKey (ent->client->pers.userinfo,
> "skin")) != NULL
> && (*info == 'f' || *info == 'F');
> }
>
> ... but I think this breaches the bounds of good taste.

Promulgating your prejudices?

Tim Rentsch

unread,
Mar 11, 2011, 3:31:49 PM3/11/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> r...@zedat.fu-berlin.de (Stefan Ram) quotes:
>>nonzero (true)
>
> This quotation from ISO/IEC 9899:1999 (E) might lead to
> better define:

Reference, please?

> #define istrue( x )( x )
> #define settrue( x )(( x )= 1 )
> #define isfalse( x )!( x )
> #define setfalse( x )(( x )= 0 )
>
> instead of
>
> #define true 1
> #define false 0
>
> . Or, possibly, if you prefer:
>
> #define istrue( x )!!(x)

Tim Rentsch

unread,
Mar 11, 2011, 3:35:32 PM3/11/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Keith Thompson <ks...@mib.org> writes:
>>are equally correct, but the shorter form is definitely *better*.
>
> This I use a my general style guideline:
>
> When two wordings are equivalent, use the shorter one.
>
> More precise:
>
> When two wordings are equivalent, and there is no other
> strong reason to prefer one of them, use the shorter one.

This is a vacuous statement unless some effort is made to
identify which reasons might be sufficiently compelling
to justify a longer wording and which others are not.

John Gordon

unread,
Mar 11, 2011, 4:23:32 PM3/11/11
to

> r...@zedat.fu-berlin.de (Stefan Ram) writes:

I disagree. There can be any number of reasons to prefer one equivalent
wording over another, and those reasons can vary wildly depending on
the problem domain.

Just to pick one random example, if you're writing user documentation you
might prefer a passage with a friendly tone versus a shorter one that
contains the same technical content but is terse and unwelcoming.

--
John Gordon A is for Amy, who fell down the stairs
gor...@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

pete

unread,
Mar 12, 2011, 12:02:05 AM3/12/11
to
John Gordon wrote:
>
> In <kfnei6d...@x-alumni2.alumni.caltech.edu> Tim Rentsch <t...@alumni.caltech.edu> writes:
>
> > r...@zedat.fu-berlin.de (Stefan Ram) writes:
>
> > > Keith Thompson <ks...@mib.org> writes:
> > >>are equally correct, but the shorter form is definitely *better*.
> > >
> > > This I use a my general style guideline:
> > >
> > > When two wordings are equivalent, use the shorter one.
> > >
> > > More precise:
> > >
> > > When two wordings are equivalent, and there is no other
> > > strong reason to prefer one of them, use the shorter one.
>
> > This is a vacuous statement unless some effort is made to
> > identify which reasons might be sufficiently compelling
> > to justify a longer wording and which others are not.
>
> I disagree.
> There can be any number of reasons to prefer one equivalent
> wording over another, and those reasons can vary wildly depending on
> the problem domain.
>
> Just to pick one random example,
> if you're writing user documentation you
> might prefer a passage with a friendly tone versus a shorter one that
> contains the same technical content but is terse and unwelcoming.


This fragment
if ((c) != '\0')
and this fragment
if (c)
are exactly equivalent,
in any context,
regardless of the type of (c).

If c was assigned the value of a byte in a string,
I would write
if (c != '\0')
instead of
if (c)

--
pete

Tim Rentsch

unread,
Mar 12, 2011, 3:52:52 AM3/12/11
to
John Gordon <gor...@panix.com> writes:

> In <kfnei6d...@x-alumni2.alumni.caltech.edu> Tim Rentsch <t...@alumni.caltech.edu> writes:
>
>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>
>> > Keith Thompson <ks...@mib.org> writes:
>> >>are equally correct, but the shorter form is definitely *better*.
>> >
>> > This I use a my general style guideline:
>> >
>> > When two wordings are equivalent, use the shorter one.
>> >
>> > More precise:
>> >
>> > When two wordings are equivalent, and there is no other
>> > strong reason to prefer one of them, use the shorter one.
>
>> This is a vacuous statement unless some effort is made to
>> identify which reasons might be sufficiently compelling
>> to justify a longer wording and which others are not.
>
> I disagree. There can be any number of reasons to prefer one equivalent
> wording over another, and those reasons can vary wildly depending on

> the problem domain. [snip example]

I believe you have misunderstood my statement. I'm not saying
there is never any reason to prefer one wording over another,
only that the quoted "general style guideline" doesn't tell
us anything. Basically all it says is, "you should use the
shorter form, except when you shouldn't". True statement,
but it doesn't tell us anything we didn't already know.

Message has been deleted

Tim Rentsch

unread,
Mar 12, 2011, 1:01:01 PM3/12/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Tim Rentsch <t...@alumni.caltech.edu> writes:
>>>>r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>>When two wordings are equivalent, and there is no other
>>>>>strong reason to prefer one of them, use the shorter one.

>>all it says is, "you should use the shorter form, except when
>>you shouldn't".
>

> When two wordings are equivalent, and you are not aware
> of a significantly good reason to prefer one of them,
> use the shorter one.
>
> (>>Significantly good<< is still vague, but this vagueness is
> intended to give the user of this rule some freedom for his
> personal taste.)

Sounds suspiciously like "Choose the shorter unless you
think it should be longer." That advice doesn't provide
any meaningful content.

Also, if there is a significantly good reason to prefer
one wording over another, the two wordings are not
equivalent, are they?

Keith Thompson

unread,
Mar 12, 2011, 3:41:02 PM3/12/11
to
Tim Rentsch <t...@alumni.caltech.edu> writes:
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>> Tim Rentsch <t...@alumni.caltech.edu> writes:
>>>>>r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>>>When two wordings are equivalent, and there is no other
>>>>>>strong reason to prefer one of them, use the shorter one.
>>>all it says is, "you should use the shorter form, except when
>>>you shouldn't".
>>
>> When two wordings are equivalent, and you are not aware
>> of a significantly good reason to prefer one of them,
>> use the shorter one.
>>
>> (>>Significantly good<< is still vague, but this vagueness is
>> intended to give the user of this rule some freedom for his
>> personal taste.)
>
> Sounds suspiciously like "Choose the shorter unless you
> think it should be longer." That advice doesn't provide
> any meaningful content.

I tend to agree.

> Also, if there is a significantly good reason to prefer
> one wording over another, the two wordings are not
> equivalent, are they?

I'd say that clarity is a "significantly good reason", even when the two
forms are exactly equivalent as far as the language is concerned.

For example, I find


if (c != '\0')

clearer than
if (c)

(Yes, I know others might find the shorter form clearer.)

J. J. Farrell

unread,
Mar 12, 2011, 7:33:49 PM3/12/11
to
Tim Rentsch wrote:
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>
>> Tim Rentsch <t...@alumni.caltech.edu> writes:
>>>>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>>> When two wordings are equivalent, and there is no other
>>>>>> strong reason to prefer one of them, use the shorter one.
>>> all it says is, "you should use the shorter form, except when
>>> you shouldn't".
>> When two wordings are equivalent, and you are not aware
>> of a significantly good reason to prefer one of them,
>> use the shorter one.
>>
>> (>>Significantly good<< is still vague, but this vagueness is
>> intended to give the user of this rule some freedom for his
>> personal taste.)
>
> Sounds suspiciously like "Choose the shorter unless you
> think it should be longer." That advice doesn't provide
> any meaningful content.

Certainly it does. I come to write a line of code; two ways of writing
it are immediately obvious to me, one longer than the other. Both have
pros and cons, the merits of which I judge to be equal. I can dither for
ever in an agony of indecision, or I can toss a coin, or I can turn to
the style guide. This rule deals exactly with this situation, albeit a
situation which is probably vanishingly rare.

> Also, if there is a significantly good reason to prefer
> one wording over another, the two wordings are not
> equivalent, are they?

The wordings being equivalent is from the compiler's point of view but
the reason for the choice is from the coder's point of view.

Message has been deleted
Message has been deleted

Tim Rentsch

unread,
Mar 13, 2011, 10:47:23 AM3/13/11
to
"J. J. Farrell" <j...@bcs.org.uk> writes:

> Tim Rentsch wrote:
>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>
>>> Tim Rentsch <t...@alumni.caltech.edu> writes:
>>>>>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>>>> When two wordings are equivalent, and there is no other
>>>>>>> strong reason to prefer one of them, use the shorter one.
>>>> all it says is, "you should use the shorter form, except when
>>>> you shouldn't".
>>> When two wordings are equivalent, and you are not aware
>>> of a significantly good reason to prefer one of them,
>>> use the shorter one.
>>>
>>> (>>Significantly good<< is still vague, but this vagueness is
>>> intended to give the user of this rule some freedom for his
>>> personal taste.)
>>
>> Sounds suspiciously like "Choose the shorter unless you
>> think it should be longer." That advice doesn't provide
>> any meaningful content.
>
> Certainly it does. I come to write a line of code; two ways of writing
> it are immediately obvious to me, one longer than the other. Both have
> pros and cons, the merits of which I judge to be equal. I can dither
> for ever in an agony of indecision, or I can toss a coin, or I can
> turn to the style guide.

If I may paraphrase: "If you can't find any other reason
to prefer one over the other, always choose the shorter one."

That still doesn't offer any guidance as to what reasons
might be good reasons to prefer one or the other, which
is my point.

> This rule deals exactly with this situation,
> albeit a situation which is probably vanishingly rare.

The rarity depends on unstated and unknown factors, and
could range anywhere from 0 to 1 depending on how those
are chosen. The same point.


>> Also, if there is a significantly good reason to prefer
>> one wording over another, the two wordings are not
>> equivalent, are they?
>
> The wordings being equivalent is from the compiler's point of view but
> the reason for the choice is from the coder's point of view.

One might have said so in the first place. The
original statement didn't have this meaning.

Tim Rentsch

unread,
Mar 13, 2011, 10:59:52 AM3/13/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Tim Rentsch <t...@alumni.caltech.edu> writes:
>>Sounds suspiciously like "Choose the shorter unless you
>>think it should be longer." That advice doesn't provide
>>any meaningful content.
>

> This was not what I wrote.

No, it isn't. That's why I said "sounds suspiciously like".

> But it has meaningful content.

In the same way that a Rorschach test has meaningful content?
What it means is all in the eye of the beholder.


>>Also, if there is a significantly good reason to prefer
>>one wording over another, the two wordings are not
>>equivalent, are they?
>

> >>Equivalent<< means >>semantically equivalent<<, here.

Then say so. I can't respond to what you're thinking,
only what you write.

Tim Rentsch

unread,
Mar 13, 2011, 11:02:11 AM3/13/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>Equivalent<< means >>semantically equivalent<<, here.
>

> Another attempt:
>
> When two pieces if code are semantically equivalent, their
> overall fitness is given as a function of the estimated
> performance, the estimated readability, the length, and
> other factors, which can be approximated as [edited]
>
> a * estimated_performance +
> b * estimated_readability +
> c * length + ...
>
> . In my case, c is negative and possibly smaller than in
> the case of the average of the programmers.

Now we're starting to get somewhere...

pete

unread,
Mar 13, 2011, 11:30:01 AM3/13/11
to
Tim Rentsch wrote:

> In the same way that a Rorschach test has meaningful content?
> What it means is all in the eye of the beholder.

... So then, the guy says to psychiatrist,
"What do you mean, I'm a pervert?"
"You're the one with all the dirty pictures!"

--
pete

Keith Thompson

unread,
Mar 13, 2011, 2:23:18 PM3/13/11
to

Yes, to a possible record for the longest conversation about
conciseness. 8-)}

Message has been deleted

Keith Thompson

unread,
Mar 13, 2011, 9:54:11 PM3/13/11
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:
> Keith Thompson <ks...@mib.org> writes:
>>Yes, to a possible record for the longest conversation about
>>conciseness. 8-)}
>
> « Je n'ai fait celle-ci plus longue que parce que je
> n'ai pas eu le loisir de la faire plus courte. »
>
> Blaise Pascal, Lettres Provinciales, XVI, 14 Dec 1656

Now, if we can just keep this thread going for another 355 years ...

John Gordon

unread,
Mar 14, 2011, 4:04:26 PM3/14/11
to

> >> > When two wordings are equivalent, and there is no other
> >> > strong reason to prefer one of them, use the shorter one.

> Basically all it says is, "you should use the shorter form, except when


> you shouldn't". True statement, but it doesn't tell us anything we
> didn't already know.

Fair enough.

It does say, though, that length is not the only criteria; without that
exception, some writers might feel obligated to always use the shorter
phrasing.

Tim Rentsch

unread,
Mar 17, 2011, 5:45:44 PM3/17/11
to
John Gordon <gor...@panix.com> writes:

> In <kfnlj0k...@x-alumni2.alumni.caltech.edu> Tim Rentsch <t...@alumni.caltech.edu> writes:
>
>> >> > When two wordings are equivalent, and there is no other
>> >> > strong reason to prefer one of them, use the shorter one.
>
>> Basically all it says is, "you should use the shorter form, except when
>> you shouldn't". True statement, but it doesn't tell us anything we
>> didn't already know.
>
> Fair enough.
>

> It does say, though, that length is not the only criteria; [snip]

It implies that, yes, and also implies that there are
circumstances where length will be the only important
determining factor. My complaint (if it may be called
a complaint) is that nothing is said about where the
dividing line is between the two kinds of criteria.

0 new messages