if(a);

N

Niklas Matthies

Readability of course is in the eye of the beholder.
Having said that, I will agree that writing if(ptr==NULL)
is better style than if(!ptr), for at least two reasons:
(1) ! is a logical "not" operator, and it is unnatural
to apply it to a pointer value (address).

The null pointer value is not an address. Hence you can read
'if (!ptr)' as 'if ptr is not an address' or 'if ptr is not an
actual pointer' (i.e. to an object). This way the logical "not"
operator becomes very natural.
(2) In order to understand the code snippet, one has to
mentally map it into if(ptr is a null pointer), which is
more directly expressed as if(ptr==NULL).

Personally, when reading 'ptr==NULL', I have to mentally translate
it to 'is not a valid pointer (value)'.
The less mental interpretation that is required, in
general, the easier the code is to read.

Right.

-- Niklas Matthies
 
J

James Kanze

(e-mail address removed) (Dan Pop) writes:

|> >> Therefore, it is a *fact* that if(p != NULL) is more readable
|> >> than if(p).

|> >Yes, but only according to your definition of readability, based on
|> >the number of people on the planet who can correctly parse the
|> >given piece of code. Apparently, in your opinion that's an
|> >appropriate definition of readability in this context. But in some
|> >other people's opinion, it may be less important how easily a
|> >completely newbie can misunderstand our code, and more important
|> >how efficiently an experienced person can read it.

|> I have yet to see proof that it makes *any* difference to the
|> *competent* programmers but I have already seen proof that
|> *experienced* programmers may not fully and correctly understand the
|> short form.

FWIW: I am an experienced programmer, with more than 20 years of C and
C++ behind me, and I still have to think about something like "if (a)";
no matter how often I see it, it still doesn't say anything to me. And
even thinking about it, I get it wrong about 5% of the time.

Of course, that's just one point of measure, but I've yet to find anyone
who had to think about the meaning of "if ( a == NULL )".
 
J

James Kanze

[...]
|> We did not get to see the code surrounding the error, which may well
|> have made it an obvious mistake, e.g.:

|> My foolish, working-code altering colleague changes this:

|> char *ptr = malloc(500);
|> if (ptr == NULL) {
|> return EXIT_FAILURE;
|> }

|> into this:

|> char *ptr = malloc(500);
|> if (ptr) {
|> return EXIT_FAILURE;
|> }

|> My guess is that close to 100% of the readers here would've spotted
|> *that* code defect.

My guess is that it would be significantly less than 100%, and that if,
instead of the readers here, you were to present it to a broad cross
section of C programmers, the percentage would be even smaller.

And of course, we don't always have that much context to help. Instead
of malloc, for example, it could be a call to someFunction, and the
treatment in the case of NULL could be considerably more complex.
 
J

James Kanze

|> En [email protected], Casper H.S. Dik va escriure:
|> >> Christian Bau wrote:
|> >> ...

|> >>> I personally wasted several days of my life because someone made
|> >>> code more "readable" by changing
|> <James Kuyper answered, missing that the meaning changed, titled by
|> the words "undefined behaviour">

|> > I think a reaction like this proves the point which is also well
|> > illustrated by the original code chaneg: it's too easy to confuse
|> > the meaning of the implied test with the opposite.

|> Which of course is more a proof that "rewriting to improve code
|> readability" is not always a good thing, rather than any
|> demonstration about whatever particular style.

Or both.

In fact, of course, we don't know the full original context, so it is
impossible to say. There are cases where rewriting to improve
readability is justified -- if I have to modify some complete spagetti,
for example, I will generally start by rewriting it cleanly, test
extensively to ensure that my rewrite has the same semantics, and then
procede to my modification. Unless I actually have the specification as
to what the code is supposed to do; in that case, I'll usually just
reimplement with no reference to the junk.

What the example did prove is that the person who modified the code
either didn't understand one of the variants, or simply slipped up in
typing. I rather suspect the latter.
 
J

James Kanze

|> If a C programmer can't parse "if (!ptr)" as "if ptr == NULL" and
|> "if (ptr)" as "if ptr != NULL" [or "if (!n)" as "if n == 0" and
|> "if (n)" as "if n != 0"] then that programmer should eschew C.

We don't always have a choice. My employers impose C++, so I program in
C++. In the past, I have used C and Java for similar reasons:).

Despite more than 20 years experience with the language, something like
if (p) still makes me pause and think. And I still get it wrong once in
awhile.

As to whether I should be considered competent or not, I'll leave it to
others to judge. My employers consider me competent, which is
important to me financially, and I do manage to write fairly complex
applications in C, C++ or Java which are correct and which the people
who had to work on them afterwards considered maintainable.
 
C

CBFalconer

Douglas A. Gwyn said:
Readability of course is in the eye of the beholder.
Having said that, I will agree that writing if(ptr==NULL)
is better style than if(!ptr), for at least two reasons:
(1) ! is a logical "not" operator, and it is unnatural
to apply it to a pointer value (address).
(2) In order to understand the code snippet, one has to
mentally map it into if(ptr is a null pointer), which is
more directly expressed as if(ptr==NULL).
The less mental interpretation that is required, in
general, the easier the code is to read.

This will probably never be noticed in the noise generated on the
thread. However:

char *ptr;

int main(void)
{
if (ptr) ....
....
}

carries the meaning "does ptr exist". It will have been
statically initialized to NULL, or (void *)0 with the intrinsic
meaning "no such beastie exists". Similarly for a NULL return
from malloc. I.e. my point is that the meaning of NULL is "I
don't exist".

Whether or not a test for NULLity should involve a specific
comparison has no specific answer. At times, the == NULL (or !=
NULL) will emphasize something or other, and is useful. At other
times it is pointless. It is simply not worth something like 60
articles with varying levels of invective.

Is this post very useless, or very very useless. Maybe useless.
 
D

Douglas A. Gwyn

CBFalconer said:
if (ptr) ....
carries the meaning "does ptr exist". It will have been
statically initialized to NULL, or (void *)0 with the intrinsic
meaning "no such beastie exists".

No, if you want to take that tack then you'd have to
say that it means "does the pointer point to an object
that exists?". But actually that is not what the test
determines. All that it determines is whether the
pointer value is not a null pointer value. That is
why if(ptr!=NULL) is the literal meaning.

Not all non-null pointers are valid.

I haven't been arguing that the usage isn't "idiomatic",
just that in order to seem "natural" one has to learn
the idiom, which would not be true if conditional
expressions had explicitly Boolean type, as the do in
many other procedural languages.
 
M

Michael Wojcik

Readability of course is in the eye of the beholder.
Having said that, I will agree that writing if(ptr==NULL)
is better style than if(!ptr), for at least two reasons:
(1) ! is a logical "not" operator, and it is unnatural
to apply it to a pointer value (address).

I disagree. First, I don't believe there's anything particularly
"natural" about pointers. Their correspondences with "real world"
entities are tenuous, so relying on intuitive understanding of
pointer operations is a recipie for disaster anyway. Second, the
idiom "!ptr" specifically does *not* refer to the pointer's value
as an "address", since it only distinguishes between two classes of
pointer values: null and non-null, and a null pointer is distinct
from any valid object address. Third, by the same reasoning, a
logical operation is perfectly reasonable; the pointer's value is
either null (false) or not-null (true), as the response to the
predicate "does this point somewhere?".
(2) In order to understand the code snippet, one has to
mentally map it into if(ptr is a null pointer), which is
more directly expressed as if(ptr==NULL).

Perhaps some need to read that as "ptr is a null pointer", but I've
never done so. It's just as possible to read it as "ptr doesn't
point anywhere", which is not expressed by "ptr==NULL" (though that's
an equivalent *C* expression, of course).

Readability certainly is a function of audience, in part because
interpretation is performed by the reader, which makes generaliza-
tions about how a particular idiom is read and interpreted (and hence
about how it should be expressed to best guide interpretation)
suspect. It's entirely possible that, for example, most of the
potential future maintainers of the C code that I write would
interpret the "if (!ptr)" idiom the way you do, and so I'd be better
off using "if (ptr==NULL)"; but that's an untestable hypothesis.
 
B

Boris Wirtz

I fail how someone can misinterpret:

if (ptr == NULL)

it's not difficult to see how someone can misconstrue the implicit operation
revered in:

if (ptr)

The fact that some (many?) people misread that this change was wrong
is ample proof that the second form is harder to read unless you can
come up with a concinving argument on how the first form can be
misinterpreted.

There was no misconception of

if (ptr)

itself, there was a misconception that both lines are equivalent.
This can be explained quite easily : both lines contain do not contain
any negations, so the brain (wrongly) regards both lines as similar, thus
equivalent. Dumb, but that's the way the brain works.

So you can conclude, that you should never mix both forms, and you
should be extremley cautious when transforming one into the other.
You can not conclude that the second one is harder to read - in fact
the equality misconception should also occur if the "if (ptr)" line
is read first.


Gruss, Boris
 
J

Joon Yew

Douglas A. Gwyn said:
No, if you want to take that tack then you'd have to
say that it means "does the pointer point to an object
that exists?". But actually that is not what the test
determines. All that it determines is whether the
pointer value is not a null pointer value. That is
why if(ptr!=NULL) is the literal meaning.

if (e)

whatever e is, the C attempts to treat it as an integer type (at least an
int). And test it for non-zero.

i.e. the compiler treats it as

if (e != 0)

if e is a pointer, the C tries to convert the pointer to an integer type,
and then compares it with zero.

Also NULL does not necessarily translates to (void*)0. The definition NULL
is implementation dependent. One C implementation may use a non-zero value
to represent NULL.

So if you really want to check for a non-NULL pointer value in an
implementation-independent way, you should code:

#include <stddef.h>

if (p != NULL)

Cheers :) Joon Yew
 
A

Arthur J. O'Dwyer

[fup to clc, dunno why this was crossposted in the first place]

if (e)
whatever e is, the C attempts to treat it as an integer type (at least an
int).
Wrong.

And test it for non-zero.
i.e. the compiler treats it as
if (e != 0)
if e is a pointer, the C tries to convert the pointer to an integer type,
and then compares it with zero.
Wrong.

Also NULL does not necessarily translates to (void*)0. The definition NULL
is implementation dependent. One C implementation may use a non-zero value
to represent NULL.

Wrong (but read the FAQ).
So if you really want to check for a non-NULL pointer value in an
implementation-independent way, you should code:
#include <stddef.h>
if (p != NULL)

Right, but only because that is the One True Way ;) (not counting that
<stddef.h> stuff, which works but is not the One True Way because
who would recognize *that* when <stdio.h> is much more common?).
Implementation independence has nothing to do with it.

Please [engage your brain and then] read the FAQ before posting.
Especially before posting to a thread in which the right answers
have been given numerous times, in a group where the right answers
are usually considered general knowledge.

-Arthur
 
M

Martin Dickopp

Joon Yew said:
if (e)

whatever e is, the C attempts to treat it as an integer type (at least
an int).

No, the implementation treats it as a scalar type, i.e. an integer,
floating-point or pointer type.
i.e. the compiler treats it as

if (e != 0)

if e is a pointer, the C tries to convert the pointer to an integer
type, and then compares it with zero.

No, if `e' has pointer type, then `e != 0' compares `e' to a null
pointer.
Also NULL does not necessarily translates to (void*)0. The definition
NULL is implementation dependent. One C implementation may use a
non-zero value to represent NULL.

`NULL' must expand to a null pointer constant, which is either an
integer constant expression with the value 0, or such an expression
cast to `void *'.
So if you really want to check for a non-NULL pointer value in an
implementation-independent way, you should code:

#include <stddef.h>

if (p != NULL)

No, `if (p != 0)' and `if (p)' are just as implementation-independent as
`if (p != NULL)'.

Martin


PS: Followup-To: comp.lang.c.
 
D

Douglas A. Gwyn

Joon said:
if (e)
whatever e is, the C attempts to treat it as an integer type (at least an
int).
Wrong.

if e is a pointer, the C tries to convert the pointer to an integer type,
and then compares it with zero.
Wrong.

Also NULL does not necessarily translates to (void*)0. The definition NULL
is implementation dependent. One C implementation may use a non-zero value
to represent NULL.

I didn't say anything about the NULL macro,
which you don't seem to understand. The macro
NULL defined in several standard headers is
required to expand to either an integer constant
expression with value 0 or such a constant cast
to (void*), regardless of how pointers are
represented. However, that has nothing to do
with the original topic.

Testing a pointer value against 0 (implicitly
or explicitly) in the source code is always a
valid way to test whether the pointer value is
that of a null pointer, regardless of how
pointers are represented. 0 is always a valid
way to write a null pointer constant, regardless
of how pointers are represented; what type a
source code constant 0 has depends on the context
in which it occurs.
 
J

James Kuyper

Joon said:
if (e)

whatever e is, the C attempts to treat it as an integer type (at least an
int). And test it for non-zero.

Wrong. It compares it with zero, regardless of type. Pointers can be
compared with zero without being converted to an integer type.
i.e. the compiler treats it as

if (e != 0)
Correct.

if e is a pointer, the C tries to convert the pointer to an integer type,
and then compares it with zero.

Incorrect. It recognizes the zero as a special construct, a "null
pointer constant", and compares it with the pointer. An implementation
is allowed to have multiple null pointers, with different
representations. I know of one segment-offset platform where all
pointers with an offset of 0 were treated as null pointers, regardless
of which segment they referred to. It is not guaranteed that a null
pointer, converted to an integer type, will be converted to an integer
value of zero. It is not guaranteed that an implementation has any
integer type that is capable of holding all the information contained in
a pointer value. It is, however, guaranteed that all null pointers
compare equal, regardless of their representations.
Also NULL does not necessarily translates to (void*)0. The definition NULL
is implementation dependent. One C implementation may use a non-zero value
to represent NULL.

So if you really want to check for a non-NULL pointer value in an
implementation-independent way, you should code:

#include <stddef.h>

if (p != NULL)

NULL and 0 are both null pointer constants. It's therefore guaranteed
that if (p != NULL) and if (p != 0) both perform exactly the same test:
they check whether p contains a null pointer value.
 

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,142
Messages
2,570,820
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top