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.
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
"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.
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"
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.
> /* 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
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
> 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.
... (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
> 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;}}}
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.
> 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.
--
(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...
[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.
Did any other code break when you fixed the definitions?
> Not coincidentally, that was the day I stopped using symbolic
> constants for Boolean values.
--
> 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;
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
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
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
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
> 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
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 .
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
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
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.
> 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
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.)
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.
>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;
}
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.)
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
[...]
> 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.
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.)
--
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)
> > 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.
[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.
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.
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;
<http://en.wikipedia.org/wiki/Illegitimi_non_carborundum>
--
Peter
Yes, that's what the joke referred to.
> 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.
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
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
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...
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
> >>>> 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
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.
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.
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
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=-
> 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?
> 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)
> 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.
> 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"
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
> 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.
> 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?
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.)
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.
> 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 <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.
> 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...
... 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
Yes, to a possible record for the longest conversation about
conciseness. 8-)}
Now, if we can just keep this thread going for another 355 years ...
> >> > 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.
> 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.