2 style questions

N

nrk

E. Robert Tisdale said:
It implies an implicit conversion

if ((bool)p)

(or

if ((int)p)

for Olde Tyme C programmers).

No conversions take place here (Olde Tyme C Programmer or not). The
controlling expression inside an if clause can be of any scalar type, not
just _Bool or int.

if ( (int) p )

which exhibits implementation defined behavior, is *NOT* the same as:

if ( p != NULL )
or
if ( p )

both of which have the same well-defined behavior as long as p is validly
initialized.
I prefer

if(NULL != p)

or

if (!(NULL == p))

because the result of the comparison is the appropriate type.

Your preference does not bother me, but your reason behind choosing it is
absurd.

-nrk.
 
K

Keith Thompson

xarax said:
For pointers, I use "if(p)" or "if(!p)". It is simple and
concise. In my mind, I understand that "if()" is testing
for non-zero versus zero, and that zero is the canonical
representation of a NULL pointer value. Folks who don't
understand that simple concept are not allowed anywhere
near my code.

I hope you mean that zero is the canonical *source* representation of
a null pointer value. It may or may not be represented all-bits-zero
at execution time.
 
K

Keith Thompson

The Real OS/2 Guy said:
So you should write

if ((p != NULL) == !TRUE)

Is at least more readable as it clearly thays that the condition is
true when the compare to NULL is true. But then you shoud write for
more clarity

if (((p != NULL) == !TRUE) == !TRUE)

But then why stop by the 3 compares? Increase it to an unlimited
amount of compares to get it really clear. Amny != is superflous but
confues to expoermented C programmmer in first step. if (p) is sowhat
of clear because ther is no need to compare the test result with
something. The test itself is anthing needed

Presumably you meant to write
if ((p != NULL) == TRUE)
rather than
if ((p != NULL) == !TRUE)

Presumably you also intended to provide a definition for TRUE, ideally
something simple like
#define TRUE 1

Given that correction, you're absolutely right on the technical issue;
"if (p)" and "if (p != NULL)" are equivalent (assuming that p is a
pointer, and assuming an appropriate #include directive so the NULL
macro is visible).

As far as the style issue is concerned, I'm not going to say that
you're wrong, but my opinion does differ from yours.

The fact that a pointer value can be used as a condition is perfectly
well defined by the C standard. It's something that all C programmers
need to be aware of (as I think everyone who's responded on this
thread already is). Anyone encountering "if (p)" in a C program
shouldn't have any trouble figuring out what it means.

However, just because C allows you to be terse, that doesn't mean you
need to be as terse as possible at all times.

Like Richard, I prefer not to take advantage of C's ability to use a
pointer value as a condition in code that I write. I prefer to make
the comparison to NULL explicit. For one thing, it makes it clearer
to the reader that p is a pointer and not an int or a boolean. My
code is likely to be read more times than it's written; if a couple of
extra tokens make it easier to read, I'll gladly spend the half-second
or so it takes to add them.

Similarly, I prefer to compare characters explicitly to '\0' (if I'm
using them as characters and not as tiny integers), and floating-point
values to 0.0.

My preference in this matter is not very strong, and I don't try to
impose it on anyone else. I can happily read code using either style.
I suspect most C programmers can do so as well.

(On the other hand, comparing something that's already boolean to true
or false is silly and potentially dangerous; that's a preference I
have sometimes tried to impose on others.)

[...]
if (p) means 'is p a valid pointer then ....'

if (!p) means 'is p an invalid pointer then ....'

What can be more clean as an self documenting statement?

if (p != NULL) means 'if p is not NULL' That is an question nobody
asks really.

C has no way to determine whether a pointer is "valid". If p is an
invalid non-null pointer (for example, if it was never initialized or
if it's been passed to free()), then "if (p)" and "if (p != NULL)" are
still precisely equvalent. In principle, testing such a pointer value
invokes undefined behavior; in practice, the condition is likely to
evaluate as true.
 
C

CBFalconer

nrk said:
E. Robert Tisdale wrote:
.... snip ...

No conversions take place here (Olde Tyme C Programmer or not).
The controlling expression inside an if clause can be of any
scalar type, not just _Bool or int.

if ( (int) p )

which exhibits implementation defined behavior, is *NOT* the
same as:

if ( p != NULL )
or
if ( p )

both of which have the same well-defined behavior as long as p
is validly initialized.
.... snip ...

Your preference does not bother me, but your reason behind
choosing it is absurd.

It's your own fault for taking _anything_ Trollsdale says
seriously. Sometimes he manages to disguise his ugly errors
beyond an outwardly seemingly plausible cover.
 
C

CBFalconer

Sander said:
or
int func(char **out1, char **out2)
{
if (out1) *out1 = malloc(100);
if (out2) *out2 = malloc(10);
return (!out1 || *out1) && (!out2 || *out2);
}

:)

You guys might consider first writing down what you are returning
for success or failure, and what constitutes success or failure.
 
T

The Real OS/2 Guy

The fact that a pointer value can be used as a condition is perfectly
well defined by the C standard. It's something that all C programmers
need to be aware of (as I think everyone who's responded on this
thread already is). Anyone encountering "if (p)" in a C program
shouldn't have any trouble figuring out what it means.

However, just because C allows you to be terse, that doesn't mean you
need to be as terse as possible at all times.

Like Richard, I prefer not to take advantage of C's ability to use a
pointer value as a condition in code that I write. I prefer to make
the comparison to NULL explicit. For one thing, it makes it clearer
to the reader that p is a pointer and not an int or a boolean. My
code is likely to be read more times than it's written; if a couple of
extra tokens make it easier to read, I'll gladly spend the half-second
or so it takes to add them.

I do it all the way - except I've to set a pointer like
if ((p = malloc(something)) == NULL) ...
but thats only because my compiler ignores the simple double parenses
and needs something (the explicite compare) to accept the assign
without warning.

O.k. I use the naked variable in any type to compare to 0 - because it
makes it more clean that a test again 0 is meant instead to some other
value - and it's shorter to write and to read.
Similarly, I prefer to compare characters explicitly to '\0' (if I'm
using them as characters and not as tiny integers), and floating-point
values to 0.0.

No comparing to '\0' is the same as to test something for been 0, so
the simple test occures. Assigning '\0' to a char is another thing as
this documents that a binary 0 char gets assigned - even as 0. gets
assigned to float - it's a bit documentation, nothing else. Comparing
a floating point against 0 makes no sense at all - because its too
seldom that it would be exactly 0.0 but might be near enough to count
so.
My preference in this matter is not very strong, and I don't try to
impose it on anyone else. I can happily read code using either style.
I suspect most C programmers can do so as well.
(On the other hand, comparing something that's already boolean to true
or false is silly and potentially dangerous; that's a preference I
have sometimes tried to impose on others.)

Comparing anything that is not clearly defined as boolean against TRUE
is always dangerous, against FALSE makes no sense too - because
testing the variable is always enough as an explicite compare is
nothing than unneeded typing.
[...]
if (p) means 'is p a valid pointer then ....'

if (!p) means 'is p an invalid pointer then ....'

What can be more clean as an self documenting statement?

if (p != NULL) means 'if p is not NULL' That is an question nobody
asks really.

C has no way to determine whether a pointer is "valid". If p is an
invalid non-null pointer (for example, if it was never initialized or
if it's been passed to free()), then "if (p)" and "if (p != NULL)" are
still precisely equvalent. In principle, testing such a pointer value
invokes undefined behavior; in practice, the condition is likely to
evaluate as true.
Oh, it has - a NULL pointer is always invalid - and is the only
pointer that can be clearly identified as such. A pointer != NULL is
pro forma always valid - even as dereferenzing it would be undefined
behavior. It is proved style to set a pointer to NULL whenever it gets
undetermined to document it is undefined - it helps significantly to
write failsave code. O.k., there is one exception - the pointer runs
out of its lifetime shortenly after it gets indetermine and is clearly
not used until then.
 
C

CBFalconer

Flash said:
.... snip ...

This I would not go for because it limits portability to
implementations implementing ISO646, but I would not have any
difficulty reading it. I find
if (p)
if (!p)

iso646 has been part of C90 since at least 1995, and possibly
1990. My point is that it is easy to miss the existence of the !
in an expression, while much harder to ignore the "not".
 
T

The Real OS/2 Guy

Depends. Users of the application I use would be less surprised (and
concerned by) an assert failure than by the application providing
incorrect results or corrupting data, and to this end I have put in
some error checking (not asserts) that aborts the program if it detects
some types of internal errors. Of course, what they really want is for
there to be no errors of any form.

Checking data and doing something to clean up asnd then stopping the
app is really required when the data is mission critical. That does
even not mean that assert() is ok, as assert hinders the program to
make a clean up before it crashes. Sure, no user weants to see an
error message - but when you can catch an error you should do that.
You're right to let the app fail with a message to the user.
 
F

Flash Gordon

iso646 has been part of C90 since at least 1995, and possibly
1990. My point is that it is easy to miss the existence of the !
in an expression, while much harder to ignore the "not".

You learn something new every day. My excuse is that I learnt from K&R2
and I can't see it in there.
 
K

Kevin Goodsell

CBFalconer said:
iso646 has been part of C90 since at least 1995, and possibly
1990. My point is that it is easy to miss the existence of the !
in an expression, while much harder to ignore the "not".

For the record, the header <ios646.h> which contains the macro 'not' was
added with Normative Addendum 1, completed in 1994 and finally accepted
in 1995.

-Kevin
 
R

Richard Heathfield

Kevin said:
That should have been <iso646.h>, of course.

Have you been programming in C++ recently, or is that just my nasty
suspicious mind working overtime?
 
K

Kevin Goodsell

Richard said:
Kevin Goodsell wrote:




Have you been programming in C++ recently, or is that just my nasty
suspicious mind working overtime?

Actually I haven't been lately, but I do a lot. 'ios' is firmly
ingrained in my mind.

-Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top