By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,898 Members | 2,022 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,898 IT Pros & Developers. It's quick & easy.

2 style questions

P: n/a
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
The arguments are that it's more readable and that if (p) is not portable.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.

So, is he right about the portability issue? is if (p) not strictly correct
C code?

2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?
Nov 14 '05 #1
Share this Question
Share on Google+
54 Replies


P: n/a
"Sander" <i@bleat.nospam.com> writes:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
These two tests are equivalent.
The arguments are that it's more readable and that if (p) is
not portable.
The latter is not true: `if (p)' is portably equivalent to `if (p
!= NULL)' for any pointer p.
2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)


It at least looks suspicious.
--
"Large amounts of money tend to quench any scruples I might be having."
-- Stephan Wilms
Nov 14 '05 #2

P: n/a
Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
I ***prefer*** the latter, if(p != NULL)
The arguments are that it's more readable
I agree with this.
and that if (p) is not portable.
This, however, is nonsense.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.
You are correct. I disagree with your style choice, but it is simply a style
choice.

So, is he right about the portability issue?
No. But he's right about the style choice. :-)
is if (p) not strictly
correct C code?
It's fine.

assert(p), however, is not (unless you have a C99 compiler).

2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}
EEK! What is this supposed to do?
This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of
the function. So, what do you think about this style?


I think it's ghastly. Specifically, I think the func() you showed us is
ghastly. I happen to agree with if(p != NULL) as being a very sensible way
to present the code. I prefer to reserve if(x) for situations where x is
clearly of Boolean intent, e.g.

int Split(vector *v, char *s, int WantDelimiters)
{
char *left = s;
char *right = left;
while(*left)
{
if(WantDelimiters)
{

etc
--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #3

P: n/a
* Thus spoke Sander <i@bleat.nospam.com>:

Hallo,
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
No. But he might prefer it for readability reasons. Many programmers
that I know consider it as good programming style.

(My version of the standard is not available right now, but:)
| Every pointer type in C has a special value called a /null pointer/,
| which is different from every valid pointer of that type, which compares
| equal to a null pointer constant, which converts to the null pointers of
| other pointer types, and which has the value "false" when used in a
| boolean context. The /null pointer constant" in C is any integer
| constant expression with the value 0, or such an expression cast to type
| void*.
(Harbinson/Steele)
The arguments are that it's more readable and that if (p) is not portable.
I use »if(!p)« and you may further meet programmers that like to use
if(p==0), if(p==(void*)0), if(p== int*)0)...
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.
As I said before I prefer the shorthand notation too, but there might be
more people that disagree on this point.
char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

So, what do you think about this style?


No.
Wolfgang.
--
"Erfahrungen -- das sind die vernarbten Wunden unserer Dummheit."
-- John Osborne
Nov 14 '05 #4

P: n/a
On Sun, 21 Dec 2003 08:48:45 +0100, in comp.lang.c , "Sander"
<i@bleat.nospam.com> wrote:
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
the two are identical. I personally find the former more readable, but
the latter is just as good.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}


This I don't like, because it mallocs two things, and doesn't make it
terribly clear its doing either.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #5

P: n/a

"Sander" <i@bleat.nospam.com> wrote in message

So, is he right about the portability issue? is if (p) not strictly correct C code?
if(p) is more expressive. For someone who doesn't know C, if(p != NULL) is
more understandable, but you can't go far in C without knowing that non-zero
equates to true and NULL = (==) 0 in C programs.
char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

So, what do you think about this style?

There's no easy solution to this. When you need to return more than one
value you have to either use a structure or use pointers. Where those values
are arrays allocated with malloc() things become messy, since you've got to
document that they have to be freed by the caller.

void func(char **out1, char **out2)

would have the benefit of showing that the two outputs were equivalent.
Similarly you would write

void getcursorpos(int *x, int *y)

int getcursorpos(int *y)

However if one value is the major return of the function, whist another is
subsidiary, then maybe the original style makes sense.

Eg in an adventure game

char *getnextroomdesc(char **error)

where very occasionally it will return 0 and set error.


Nov 14 '05 #6

P: n/a
> > char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

So, what do you think about this style?
There's no easy solution to this. When you need to return more than one
value you have to either use a structure or use pointers. Where those

values are arrays allocated with malloc() things become messy, since you've got to document that they have to be freed by the caller.


Ai, I was not very clear about the second.
It's not about returning two values, it's about returning dynamic memory
from a function.
Sometime he does something like this:
char *fun(void) { return malloc(10); }

and sometimes this:
void fun(char **s) { *s = malloc(10); }

I consider this very bad style, to the point that it's really crappy
unexperienced C coding.
Nov 14 '05 #7

P: n/a
"Malcolm" <ma*****@55bank.freeserve.co.uk> writes:
if(p) is more expressive. For someone who doesn't know C, if(p != NULL) is
more understandable, but you can't go far in C without knowing that non-zero
equates to true and NULL = (==) 0 in C programs.


In a program that I develop, there are several types of handles
with special null values. For example, a variable of type
msg_handle_t can have the special value MSG_HANDLE_NULL, which
means the handle does not refer to any message. However,
MSG_HANDLE_NULL is defined as 0 on one platform and 0xFFFF on
another, so "if (handle)" would be a bug; I must use "if
(handle != MSG_HANDLE_NULL)" instead. Out of habit, I then use
"if (pointer != NULL)" as well.
Nov 14 '05 #8

P: n/a
On Sun, 21 Dec 2003 12:04:17 +0100, in comp.lang.c , "Sander"
<i@bleat.nospam.com> wrote:
It's not about returning two values, it's about returning dynamic memory
from a function.
absolutely nothing wrong with that. Useful technique on occasions -
imagine you're loading a buffer with data from somewhere (disk,
network, whatever), the caller can't know how much memory to allocate,
so get the callee to do it. The alternative is to repeatedly call the
callee, which is not CPU friendly.
Sometime he does something like this:
char *fun(void) { return malloc(10); }

and sometimes this:
void fun(char **s) { *s = malloc(10); }
Well, its inconsistent to mix styles, but either is ok. Personally
I'd prefer to pass in the pointer, and return a status instead of
void.
I consider this very bad style, to the point that it's really crappy
unexperienced C coding.
On the contrary, its a well established technique. What it /does/
require is more care in your documentation and in freeing the memory
afterwards. So its a more *dangerous* technique. But as they say, its
a poor atom blaster that doesn't point both ways.


--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #9

P: n/a
Richard Heathfield wrote:
is if (p) not strictly
correct C code?
It's fine.

assert(p), however, is not (unless you have a C99 compiler).


It isn't? This is a genuine surprise... Why is this?

Best regards,

Sidney

Nov 14 '05 #10

P: n/a
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:ce********************************@4ax.com...
On the contrary, its a well established technique. What it /does/
require is more care in your documentation and in freeing the memory
afterwards. So its a more *dangerous* technique. But as they say, its
a poor atom blaster that doesn't point both ways.


It's certainly more dangerous and I already found a mem leak in his own
code.
I wonder what would happen if I started using that code.
Nov 14 '05 #11

P: n/a
Sander wrote:

1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
The arguments are that it's more readable and that if (p) is not portable.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.

So, is he right about the portability issue? is if (p) not strictly correct
C code?
I agree with you. Both styles are portable.

2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?


Very ugly. I cannot conceive of a legitimate use for the result.
I can conceive of several illegitimacies.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #12

P: n/a
nrk
Sidney Cadot wrote:
Richard Heathfield wrote:
is if (p) not strictly
correct C code?

It's fine.

assert(p), however, is not (unless you have a C99 compiler).


It isn't? This is a genuine surprise... Why is this?

Best regards,

Sidney


assert works only on expressions of integer type in C89, and results in UB
otherwise. So, you should write assert(p != 0) or assert(p != NULL).
However, in C99, it takes expressions of any scalar type, so assert(p) is
fine.

-nrk.
Nov 14 '05 #13

P: n/a
Sidney Cadot wrote:
Richard Heathfield wrote:
is if (p) not strictly
correct C code?

It's fine.

assert(p), however, is not (unless you have a C99 compiler).


It isn't? This is a genuine surprise... Why is this?


In C90, assert takes an expression of int type. If p is of some pointer
type, then the expression

p

has pointer type, not int type.

The expression

p != NULL

has int type, and is thus suitable for use in assert(). As I have already
hinted, this changed in C99, so that assert takes a scalar expression.
Therefore, in C99, assert(p) is correct (albeit not as readable IMHO as
assert(p != NULL), but that's a style issue).

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #14

P: n/a
On Sun, 21 Dec 2003 07:48:45 UTC, "Sander" <i@bleat.nospam.com> wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
Ask him why he doesnt use
if ((p != NULL) != 0) != 0)
or better
if (p == (0 == 0 && 0 == 0x00 && 0 == NULL && 0 == 000))
or
if (p != (NULL - 0))
or
if ((p + 0) != (0*0))
or
if (!p == !NULL)
or......

because when he needs a superflous compare he should never stp by one
but by an infinite number of compares to get it.

It seems he has never learnd programming in C.

Ask him to name the point in the standard that forbits if(p).

Ask him too why he does thing that if(p) should give something
different than
if ((p + 0 - '0' - '0') != ('0' - '0' + 0)

or any other constrct that needs more to type.

C has lots of possibilitzies to spend useless keystrokes to get
something written - but even lots of shorthands to make something easy
to type and to understund.
The arguments are that it's more readable and that if (p) is not portable.
Shows only that he knows absolutely nothing about he tells. Tell him
he should learn programming in C before he starts to tell about.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.
You're right that if(p) is equal to if (p == (0 == NULL == 0x00 == 000
== (0+0))

So, is he right about the portability issue? is if (p) not strictly correct
C code?
He is absolutely wrong - not only for compatibility but for
readability too. Tell him C is NOT C64 BASIC where you have no chance
to make tests for 0/NULL/zero/'\0' clean and short.

He looks like a beginner who has never learned right C.
2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}
Hm, that's a method to allocate 2 different, independant areas of
memory. Iteresting is if he is checking both results of that fuction
for success or if he assumes errornousely that this method would
always return both or none requested areas. There are possibilites
that both, one or none of the malloc() may fail. This kond of function
does nothing than to hide that there are more than one memory area
gets allocated. Looks at least as a fine source for creating memory
leaks.

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?

You're compleately right.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #15

P: n/a
On Sun, 21 Dec 2003 08:57:44 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
I ***prefer*** the latter, if(p != NULL)
The arguments are that it's more readable


I agree with this.


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
and that if (p) is not portable.


This, however, is nonsense.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.


You are correct. I disagree with your style choice, but it is simply a style
choice.

So, is he right about the portability issue?


No. But he's right about the style choice. :-)
is if (p) not strictly
correct C code?


It's fine.

assert(p), however, is not (unless you have a C99 compiler).


assert() is ALWAYS a source of confusing the user and destroying data
consistency! assert is NOT designed to test data! It is only designed
to test the program itself to catch programming errors. For testing
errors on data use the if or the ?: operator. Do the approciate
actions in case of error - but don't use assert.

assert() is originated to catch errors a programmer may do. For that
it is fine to let the program crash at the earliest possible moment
because that makes it more simple to dedect the programming error -
even as the data the program handles may get destroyed. But for that
you're in the debug phase.
I think it's ghastly. Specifically, I think the func() you showed us is
ghastly. I happen to agree with if(p != NULL) as being a very sensible way
to present the code. I prefer to reserve if(x) for situations where x is
clearly of Boolean intent, e.g.

int Split(vector *v, char *s, int WantDelimiters)
{
char *left = s;
char *right = left;
while(*left)
{
if(WantDelimiters)
{

etc

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.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #16

P: n/a
On Sun, 21 Dec 2003 11:04:17 UTC, "Sander" <i@bleat.nospam.com> wrote:
char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

So, what do you think about this style?
There's no easy solution to this. When you need to return more than one
value you have to either use a structure or use pointers. Where those

values
are arrays allocated with malloc() things become messy, since you've got

to
document that they have to be freed by the caller.


Ai, I was not very clear about the second.
It's not about returning two values, it's about returning dynamic memory
from a function.
Sometime he does something like this:
char *fun(void) { return malloc(10); }


Oh, its really fun-ny for a maintenancer to get all the hidden malloc.
and sometimes this:
void fun(char **s) { *s = malloc(10); }

I consider this very bad style, to the point that it's really crappy
unexperienced C coding.

Tell him that he should increas the number of different interfaces to
do the same thing. It makes the maintenancer happy to find all the
different interfaces to get exactly the same thing done. He can do
that by creating functions that does not only accept pointer to
pointers but pointers to pointers to pointers..... and return values
only that way, because it is always irretating to find functions not
returning directly but using pointers to pointers...... It will make
maintenance so easy to have only functions returning void but using
parameters to get results back.

Tell him that the best way is always NOT to use arithmetic operators
like +,-,*,/ but use functions that receive pointers to the values
they have to read and pointers to pointers to pointers to give the
value of the simple operation back.

A simple wrapper auround malloc is too easy. Tell him he should write
wrapper functions around the functions and then wrappers around the
wrappers for each statement he has to produce. This will make
maintenance a bit more complicated as he tries to do yet.

To get the final state of confusing maintenancers he should use
pointers to pointers to pointers of functions and use only them to
build the call tree to get each single statement done. As this makes
maintenance so asy he will save his job for the next thoused years
because there will be nobody able to maintenance his code.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #17

P: n/a
Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
The arguments are that it's more readable and that if (p) is not portable.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.


Hello,

You are right about the portability issue. Of course both versions are
perfectly portable. Now I am only an occasional C programmer but I have
learned to put the constant first in comparisons, because especially when
testing for "equals", it makes the compiler complain when you are using "="
instead of "==". Example:

if (CONST == a) ...

and not

if (a == CONST) ...

The easy made error

if (a = CONST)

can be nasty since it always returns TRUE, while CONST = a gives you an
"lvalue" error.

So I would go with your version of just using if(p). Going with his, I'd
change to if (NULL != p).

Just my two cents

Cheers

Jens
Nov 14 '05 #18

P: n/a
Mac
On Sun, 21 Dec 2003 08:48:45 +0100, Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
The arguments are that it's more readable and that if (p) is not portable.
I said the first is a style issue and that I think if(p) is more readable
and that the second is plain wrong.

So, is he right about the portability issue? is if (p) not strictly correct
C code?

Others have explained that "if (p)" and "if (p != NULL)" are functionally
equivalent. I prefer to write if "(p != NULL)" because in my situation I
cannot assume that everyone who reads the code is an experienced C
prorgrammer. I myself have seldom been paid directly to produce C code.
Usually the code is incidental to something else, or written just for fun.

When I am reading code, if(p) doesn't bother me in the least. The only
problem would be if it were in a context where it was difficult to find
out what type p is. This is an unlikely scenario, and anyway, most
programming oriented editors let you jump right to the declaration.
2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

I'm not sure what you mean.
This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?


On an unrelated note, it sounds like you have major issues with this
programmer. If your goal is to get along with him/her, I'm not sure that
proving you are right and that, in addition, his/her code sucks, is going
to help you reach your goal.

Programming is easy. Finding the right balance between accomodation and
stubborness is hard, particularly when you are right.

Mac

Nov 14 '05 #19

P: n/a
"Jens Prüfer" <no****@jens-pruefer.de> wrote in message
news:bs************@ID-51784.news.uni-berlin.de...
Sander wrote:

/snippage about if(p) versus if(p != NULL)/
You are right about the portability issue. Of course both versions are
perfectly portable. Now I am only an occasional C programmer but I have
learned to put the constant first in comparisons, because especially when
testing for "equals", it makes the compiler complain when you are using "="
instead of "==". Example:

if (CONST == a) ...

and not

if (a == CONST) ...

The easy made error

if (a = CONST)

can be nasty since it always returns TRUE, while CONST = a gives you an
"lvalue" error.

So I would go with your version of just using if(p). Going with his, I'd
change to if (NULL != p).

Just my two cents

Cheers

Jens


Yes, for non-pointers, I generally put the constant on
the left and the variable on the right. This is a religious
style issue, similar to where braces are put (at the end
of the line or on a line by itself), so expect some flames.
I adopted that style after getting burned by the typo error
"if(variable = constant)". I haven't looked back since and
have no regrets.

Years ago, I had an instructor that spent a few minutes
"fixing" my code when I asked an unrelated question, so that
he could then proceed to read my code and answer the question.
He changed every occurance of "constant == variable" to
"variable == constant". I asked what difference it made and
he sheepishly acknowledged that it made no difference.

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.
--
----------------------------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS!
Nov 14 '05 #20

P: n/a
Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
"Must" is obviously wrong.
The arguments are that it's more readable
Some people make this claim, so I believe that it is true for _them_. It
is not true for me, and, I suspect, it is not true for most experienced C
programmers.
and that if (p) is not portable.
This is completely false. Do not take any further advice from anyone
making such obviously false statements.

[...] Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?


Failure to check the return value from malloc is much worse than a "style
issue." If this failure is in supposedly professional code, it shows
incompetence. The use of hard-coded magic numbers shows a cavalier
indifference to maintenance unbecoming a professional.


--
Martin Ambuhl

Nov 14 '05 #21

P: n/a
In article <bs**********@news1.tilbu1.nb.home.nl>, i@bleat.nospam.com says...
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:ce********************************@4ax.com...
On the contrary, its a well established technique. What it /does/
require is more care in your documentation and in freeing the memory
afterwards. So its a more *dangerous* technique. But as they say, its
a poor atom blaster that doesn't point both ways.


It's certainly more dangerous and I already found a mem leak in his own
code.


As a rule of thumb if you can avoid splitting your functions in such a way that
you allocate memory that is to be freed by another function, then you will have
fewer memory leak problems. However, there are tools and mechanisms that can
help you with those issues, and you have to consider the cost of alternatives:

1) If you use global/static memory then you typically end up with re-entrancy
or multithreading restrictions.
2) If you force memory allocation-usage-then freeing within each of your
functions, then you code may become inflexible. You can try to improve your
flexibility by using callbacks and automatic iteration over those callbacks in
these functions, however this kind of thing can be convoluted and it can be
complicated to maintain a sensible thread of the execution sequence.

Usually more important than the details of passing allocated memory out of
functions, is the semantics of the datastructures that are passed around. If,
for example, you only pass out completely initialized objects (which may
contain allocated sub-parts) that have been wrapped in a typedef or struct
definition, then its usually easier to simply map semantics to the object in an
intuitive way, rather that worry about what could potentially go wrong from
misuse of the details of your objects.

You can find an example of what I am talking about in: http://bstring.sf.net/ .
Its just a string library -- it allocates memory for strings that it passes
out, and there is no issue so long as at some point those strings are passed
back to the destruction function in the library.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 14 '05 #22

P: n/a
The Real OS/2 Guy wrote:
On Sun, 21 Dec 2003 08:57:44 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
Sander wrote:
> 1.
> I was having a discussion with somebody and I think it's just
> religious. We are developing some software and he was looking through
> my code. I use if (pointer) to test a pointer for NULL. He says it must
> be if (p!=NULL).
I ***prefer*** the latter, if(p != NULL)
> The arguments are that it's more readable


I agree with this.


So you should write

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


That doesn't follow. For a start, TRUE is undeclared. Secondly, if you
declared it and then gave it a non-pathological value - for a name like
TRUE I'd expect it to be non-zero - you would find that you have reversed
the sense of the test and introduced a bug. Thirdly, it is less readable
than the simple if(p != NULL), IMHO.
assert(p), however, is not (unless you have a C99 compiler).


assert() is ALWAYS a source of confusing the user and destroying data
consistency!


No, it isn't.
assert is NOT designed to test data!


I never said otherwise. By all means search the archives for evidence of my
position on assert.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #23

P: n/a
On Sun, 21 Dec 2003 19:00:26 UTC, "Mac" <fo*@bar.net> wrote:
Others have explained that "if (p)" and "if (p != NULL)" are functionally
equivalent. I prefer to write if "(p != NULL)" because in my situation I
cannot assume that everyone who reads the code is an experienced C
prorgrammer.
Hm, an unexperient C programmer has to learn it anyway. So when h/sh/e
fails over that ist time for him to learn more about C.

At least not an argument.

I myself have seldom been paid directly to produce C code.
Usually the code is incidental to something else, or written just for fun.

When I am reading code, if(p) doesn't bother me in the least. The only
problem would be if it were in a context where it was difficult to find
out what type p is. This is an unlikely scenario, and anyway, most
programming oriented editors let you jump right to the declaration.


Dosn't mater what type p is. When one had used 'p' for thome type
other as a pointer you would fall about that some point earlier and
whine about the abstuse naming the programmer was using - even as the
name p is allwowed for any data type the implicit thinking of an
human programmer would assign that name to an pointer type, not
struct, int or other.

in an conditional expression any C programmer would assign an single
variable name with

C syntax human reads based on code content
-------- -----------
if (x) is x TRUE?
if (!x) is x false?
if (x) is x 0/0x00/000/zero
while (p) while pointer is valid?
for (; y; ) while y is true?
for (; y; ) has y reached 0?
for (; !p; ) until pointer is valid
......

as s/h/e knows that C makes an implicite compare to (type) 0 it's more
easy to
read c = p ? *p++ : 0 as 'when p is valid then assign content of that
p points to to c and increment the pointer, else assign 0 to c' as
when 'p is NULL then pointer is valid and ....'

Comparing explicite to (type)0 is done only by very unexperienced C
programmers (and only if they have learned another programming
language prior).

2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}


I'm not sure what you mean.


A special case to hide malloc from to be visible, to make code more
complicated by using wrappers around malloc, to make maintenance more
complicate.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #24

P: n/a

"Jens Prüfer" <no****@jens-pruefer.de> wrote in message

Now I am only an occasional C programmer but I have
learned to put the constant first in comparisons, because especially
when testing for "equals", it makes the compiler complain when you are
using "=" instead of "==". Example:

if (CONST == a) ...

and not

if (a == CONST) ...

It is a pain that if(x = 100) happens to be a legal C construct. Not all
compilers warn about it.
However if(100 = x) is much more difficult to read - like spelling a work
backwards the effect of one such line is small, but the cumulative effect of
many such features is to make reading code very difficult.
if(CONST == x) lulls you into a false sense of security, because there can
be no protection from if(N = i) (N and i both variables).
Nov 14 '05 #25

P: n/a
Malcolm wrote:

It is a pain that if(x = 100) happens to be a legal C construct. Not all
compilers warn about it.
However if(100 = x) is much more difficult to read - like spelling a work
backwards the effect of one such line is small, but the cumulative effect of
many such features is to make reading code very difficult.
I wouldn't say it's "much more difficult." I haven't personally adopted
the technique, mainly because I don't really like the way it looks and
reads, but I think I could get used to it very quickly if I did start
using it (which I've been considering doing). The thing is, /any/ C
construct is difficult to read if you aren't accustomed to it, and in
this particular case it only requires reading from right to left instead
of left to right. C programmers are already used to reading that
direction (or from the inside out) in declarations. So I don't accept
readability is a major argument against this technique.
if(CONST == x) lulls you into a false sense of security, because there can
be no protection from if(N = i) (N and i both variables).


Yes, it is one of many C "quick fixes" that don't solve the real
problem, but do catch some instances (like NULLing freed pointers).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #26

P: n/a
Sander wrote:
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).


Maybe I'm weird, but I kind of think that

if (p)

is (slightly) easier to read than

if (p != NULL)

But I also think that

if (p == NULL)

is (significantly) easier to read than

if (!p)

I guess this is because 'if (p)' and 'if (p == NULL)' avoid negatives.
Negations (!, !=) tend to be confusing to me - expressions with fewer
negations are usually much easier to understand.

Does anyone else feel this way? Or am I just crazy?

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #27

P: n/a
Malcolm wrote:
However if(100 = x) is much more difficult to read
Well, the compiler will have no problem reading it on your behalf and
drawing your attention to the error.
- like spelling a work
backwards the effect of one such line is small, but the cumulative effect
of many such features is to make reading code very difficult.
I have not found this to be the case. Nevertheless, you are in good company,
since Dan Pop agrees with you 100% on this issue. I'm sure that will be of
some comfort to you. ;-)
if(CONST == x) lulls you into a false sense of security, because there can
be no protection from if(N = i) (N and i both variables).


No, it doesn't lull any sensible programmer into a false sense of security.
const==var is not a silver bullet, and nobody with any sense would pretend
otherwise. It's just a useful device, not a magic wand.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #28

P: n/a
On Sun, 21 Dec 2003 14:36:58 +0100, in comp.lang.c , "Sander"
<i@bleat.nospam.com> wrote:
I wonder what would happen if I started using that code.


You'd end up bugfixing it, and then the technique would work fine :-)
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #29

P: n/a
Kevin Goodsell wrote:
Sander wrote:
.... snip ...
But I also think that

if (p == NULL)

is (significantly) easier to read than

if (!p)

I guess this is because 'if (p)' and 'if (p == NULL)' avoid negatives.
Negations (!, !=) tend to be confusing to me - expressions with fewer
negations are usually much easier to understand.


Another possibility:

#include <iso646.h>
.....
if (not p)

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #30

P: n/a
In article <bs**********@news4.tilbu1.nb.home.nl>, i@bleat.nospam.com says...
1.
I was having a discussion with somebody and I think it's just religious.
We are developing some software and he was looking through my code.
I use if (pointer) to test a pointer for NULL. He says it must be if
(p!=NULL).
They are identical. The issue is not which one you choose, but rather that it
matters at all. If either of you have a problem with one method over the other
then its that person's problem. And its a serious one -- if a person is unable
to see a trivial equivalence in their mind, then its indicative of an improper
focus or otherwise very low mental ability.

One has religious arguments about religion, not technical equivalents. The
only merit of caring is that leaving off the != NULL has fewer characters, and
thus occupies less screen space -- but its horizontal screen space which
rarely matters.
The arguments are that it's more readable and that if (p) is not portable.
"if (p)" is portable, and since it has an equivalent meaning and can't really
be mistaken to mean something else, it can't be less readable.
I said the first is a style issue [...]
Its a non-issue. They are the same thing. You lose IQ points for every second
you waste talking to your codeveloper about it. You don't have more important
issues to talk about?
2.
Then I started looking through his code and what I noticed that he very
often does things like this:

char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

This might also be a style issue, but it's a style where it's very easy to
introduce bugs (and indeed I found a few)
and even more easy to introduce bugs if you don't know the internals of the
function. So, what do you think about this style?


For me, the value of encapsulating blocks of code into functions is for the
functions to take responsibility for credibly translating input parameters to
output parameters. If a function, such as this, is essentially perform two
side-effects, it had better be worth while to do so.

I would be very suspicious of the code above, because both mallocs are not
stored in the same structure. Hence this inherently assumes that some higher
level logic is going to tie those two mallocs together which means that "func"
is not taking responsibility for tying them together. There are also 3
possible error conditions (each malloc failing, or both of them failing) all of
which have to be determined by higher level code. For the same semantics, I
would rewrite the above as:

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

In this way its more obvious that there are two outputs (since neither
parameter is decorated as "const") and the return value will tell you whether
or not there was any failure at all. Also the effect of passing in a NULL
pointer will have the effect of deactivating that output rather than simply
leading to undefined behaviour.

For someone like me, its hard to justify writing a function like the above,
however. The reason for having two mallocs *must* be because out1 and out2 are
somehow tied together possibly in the same object. Also if these are really
"char *"'s why don't you also at least initialize them with '\0's in them?
Passing around bare mallocs (i.e., where the contents are indeterminant) is
generally kind of useless.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 14 '05 #31

P: n/a
On Sun, 21 Dec 2003 21:10:50 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
The Real OS/2 Guy wrote:
On Sun, 21 Dec 2003 08:57:44 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
Sander wrote:

> 1.
> I was having a discussion with somebody and I think it's just
> religious. We are developing some software and he was looking through
> my code. I use if (pointer) to test a pointer for NULL. He says it must
> be if (p!=NULL).

I ***prefer*** the latter, if(p != NULL)

> The arguments are that it's more readable

I agree with this.


So you should write

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


That doesn't follow. For a start, TRUE is undeclared. Secondly, if you
declared it and then gave it a non-pathological value - for a name like
TRUE I'd expect it to be non-zero - you would find that you have reversed
the sense of the test and introduced a bug. Thirdly, it is less readable
than the simple if(p != NULL), IMHO.


Hm, rally? #define TRUE to something that is NOT 0. Now tell me how
!TRUE can be evaluated to something else than 0.
assert(p), however, is not (unless you have a C99 compiler).


assert() is ALWAYS a source of confusing the user and destroying data
consistency!


No, it isn't.


A user who is not a programmer gets a shock, a live crisis if he gets
a screen saying 'core dump' or simply 'trap' or when his GUI program
ends commentless......

assert() is designed to break the program at the point it is called.
This confuses any user - even as it helps any developer to catch
errors s/h/e or her/his colleauge has made.
assert is NOT designed to test data!


I never said otherwise. By all means search the archives for evidence of my
position on assert.

Newsgroups are not to communicate privately. If I had mean you in
special I had sayed so.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #32

P: n/a
nrk
The Real OS/2 Guy wrote:
On Sun, 21 Dec 2003 21:10:50 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
The Real OS/2 Guy wrote:
> On Sun, 21 Dec 2003 08:57:44 UTC, Richard Heathfield
> <do******@address.co.uk.invalid> wrote:
>
>> Sander wrote:
>>
>> > 1.
>> > I was having a discussion with somebody and I think it's just
>> > religious. We are developing some software and he was looking
>> > through my code. I use if (pointer) to test a pointer for NULL. He
>> > says it must be if (p!=NULL).
>>
>> I ***prefer*** the latter, if(p != NULL)
>>
>> > The arguments are that it's more readable
>>
>> I agree with this.
>
> So you should write
>
> if ((p != NULL) == !TRUE)


That doesn't follow. For a start, TRUE is undeclared. Secondly, if you
declared it and then gave it a non-pathological value - for a name like
TRUE I'd expect it to be non-zero - you would find that you have reversed
the sense of the test and introduced a bug. Thirdly, it is less readable
than the simple if(p != NULL), IMHO.


Hm, rally? #define TRUE to something that is NOT 0. Now tell me how
!TRUE can be evaluated to something else than 0.


You are missing Richard's point. If TRUE is non-zero, then your test is the
exact opposite of what Richard was testing using:
if ( p != NULL )

If TRUE is zero, your test is obfuscated and way less readable than
Richard's.

All this just goes to show that Richard's style preference is in no way
comparable to your absurdity, and that your arguments against it are
meritless. FWIW, my own preference doesn't match Richard's. I prefer a
simple if ( p ), as it saves a few keystrokes without reducing readability
IMO.

To belabor the obvious:
/* if p is not NULL */
if ( p != NULL )

/* For TRUE == 1, this is the same as above
and probably what you intended to say */
if ( (p != NULL) == TRUE )

/* For TRUE != 0, this is the negation of above */
if ( (p != NULL) == !TRUE )
/* or if ( !( p != NULL) ) or if ( p == NULL ) */

-nrk.

<snip>

Nov 14 '05 #33

P: n/a
Sander <i@bleat.nospam.com> spoke thus:
Ai, I was not very clear about the second.
It's not about returning two values, it's about returning dynamic memory
from a function. I consider this very bad style, to the point that it's really crappy
unexperienced C coding.


It has to have *some* value, otherwise why would *so* many people
write and use the ubiquitous (but nonstandard!) strdup()?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #34

P: n/a
nrk wrote:
You are missing Richard's point. If TRUE is non-zero, then your test is
the exact opposite of what Richard was testing using:
if ( p != NULL )

If TRUE is zero, your test is obfuscated and way less readable than
Richard's.

All this just goes to show that Richard's style preference is in no way
comparable to your absurdity, and that your arguments against it are
meritless.
I couldn't have put it better myself.
FWIW, my own preference doesn't match Richard's. I prefer a
simple if ( p ), as it saves a few keystrokes without reducing readability
IMO.


I just wanted to add that I don't think if(p) is unreadable. I just happen
to prefer to reserve if(foo) for testing the values of objects whose
purpose is clearly Boolean in nature. Examples include:

if(!done)
if(isalpha((unsigned char)ch))
if(PrintSpoolIsFull)

I know I'm not unique in having this preference, but on the other hand I'm
not silly enough to think I can persuade the whole world to fall into line,
so I'm perfectly content to read code that uses your preference.

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #35

P: n/a
"Paul Hsieh" <qe*@pobox.com> wrote in message
news:MP************************@news.sf.sbcglobal. net...
int func (char ** out1, char ** out2) {
if (out1) *out1 = malloc (100);
if (out2) *out2 = malloc (10);
return (out1 == NULL || *out1 != NULL)
&& (out2 == NULL || *out2 != NULL);
}


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

:-)
Nov 14 '05 #36

P: n/a
nrk wrote:
I prefer a simple

if (p)

as it saves a few keystrokes without reducing readability IMO.


It implies an implicit conversion

if ((bool)p)

(or

if ((int)p)

for Olde Tyme C programmers).

I prefer

if(NULL != p)

or

if (!(NULL == p))

because the result of the comparison is the appropriate type.

Nov 14 '05 #37

P: n/a
"Sander" <i@bleat.nospam.com> wrote in message news:<bs**********@news4.tilbu1.nb.home.nl>...
char *func(char **out)
{
*out = malloc(100);
return malloc(10);
}

So, what do you think about this style?
There's no easy solution to this. When you need to return more than one
value you have to either use a structure or use pointers. Where those

values
are arrays allocated with malloc() things become messy, since you've got

to
document that they have to be freed by the caller.


Ai, I was not very clear about the second.
It's not about returning two values, it's about returning dynamic memory
from a function.


Nothing wrong with that. I generally abstract out allocation and
deallocation of resources, for example:

#include <stdio.h>

typedef ... thing;

thing *new_thing (void)
{
thing *tmp = malloc (sizeof *tmp);
if (!tmp)
{
/* report out of memory */
}
else
{
/* initialize tmp to default values */
}

return tmp;
}

void destroy_thing (thing *t)
{
if (t)
{
/* if any of t's components were also */
/* allocated dynamically, release them */
/* first */
free (t);
}
}

int main (void)
{
thing *something;

something = new_thing ();
do_something_with (something);
destroy_thing (something);

return 0;
}
Sometime he does something like this:
char *fun(void) { return malloc(10); }
If you're going to take the time and trouble to wrap a function around
malloc(), one would hope that you also add some logic to detect and
report memory allocation failures. Otherwise you might as well just
call malloc() directly.

and sometimes this:
void fun(char **s) { *s = malloc(10); }

I consider this very bad style, to the point that it's really crappy
unexperienced C coding.


There's nothing wrong with the second form (although I'd check to see
if malloc() succeeded and return a status value).

Don't knock abstraction. Your coworker may not necessarily know what
he's doing, but wrapping primitive library calls in higher-level
abstract functions is hardly bad practice.
Nov 14 '05 #38

P: n/a
nrk
E. Robert Tisdale wrote:
nrk wrote:
I prefer a simple

if (p)

as it saves a few keystrokes without reducing readability IMO.
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.
Nov 14 '05 #39

P: n/a
nrk wrote:
Your preference does not bother me
but your reason behind choosing it is absurd.


Plonk!

Nov 14 '05 #40

P: n/a
In article <3F**************@jpl.nasa.gov>,
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote:
nrk wrote:
Your preference does not bother me
but your reason behind choosing it is absurd.


Plonk!


That's what I call progress: A troll who plonks himself.
Nov 14 '05 #41

P: n/a
"xarax" <xa***@email.com> writes:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 14 '05 #42

P: n/a
"The Real OS/2 Guy" <os****@pc-rosenau.de> writes:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 14 '05 #43

P: n/a
nrk wrote:
E. Robert Tisdale wrote:
.... snip ...

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.

.... 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.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #44

P: n/a
Sander wrote:
"Paul Hsieh" <qe*@pobox.com> wrote in message
int func (char ** out1, char ** out2) {
if (out1) *out1 = malloc (100);
if (out2) *out2 = malloc (10);
return (out1 == NULL || *out1 != NULL)
&& (out2 == NULL || *out2 != NULL);
}


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.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #45

P: n/a
On Tue, 23 Dec 2003 00:52:20 UTC, Keith Thompson <ks***@mib.org>
wrote:
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.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #46

P: n/a
On Mon, 22 Dec 2003 12:09:55 +0000 (UTC)
"The Real OS/2 Guy" <os****@pc-rosenau.de> wrote:
On Sun, 21 Dec 2003 21:10:50 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:
The Real OS/2 Guy wrote:
On Sun, 21 Dec 2003 08:57:44 UTC, Richard Heathfield
<do******@address.co.uk.invalid> wrote:

> Sander wrote:
>
> > 1.
> > I was having a discussion with somebody and I think it's just
> > religious. We are developing some software and he was looking
through> > my code. I use if (pointer) to test a pointer for NULL.
He says it must> > be if (p!=NULL).
>
> I ***prefer*** the latter, if(p != NULL)
>
> > The arguments are that it's more readable
>
> I agree with this.

So you should write

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


That doesn't follow. For a start, TRUE is undeclared. Secondly, if
you declared it and then gave it a non-pathological value - for a
name like TRUE I'd expect it to be non-zero - you would find that
you have reversed the sense of the test and introduced a bug.
Thirdly, it is less readable than the simple if(p != NULL), IMHO.


Hm, rally? #define TRUE to something that is NOT 0. Now tell me how
!TRUE can be evaluated to something else than 0.


So what you've changed it to is
if ((p != NULL) == 0)
this is different from
if (p != NULL)
because the above is the same as
if ((p != NULL) == 1)
I think you meant
if ((p != NULL) != !TRUE)
which is introducing more negations and hence making it less readable.

My personal preference is
if (p != NULL)
or for integers used as integers
if (i != 0)
or for integers used as booleans/flags
if (b)
> assert(p), however, is not (unless you have a C99 compiler).

assert() is ALWAYS a source of confusing the user and destroying
data consistency!


No, it isn't.


A user who is not a programmer gets a shock, a live crisis if he gets
a screen saying 'core dump' or simply 'trap' or when his GUI program
ends commentless......

assert() is designed to break the program at the point it is called.
This confuses any user - even as it helps any developer to catch
errors s/h/e or her/his colleauge has made.


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.
--
Flash Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spam, it is real and I read it.
Nov 14 '05 #47

P: n/a
On Mon, 22 Dec 2003 01:55:38 GMT
CBFalconer <cb********@yahoo.com> wrote:
Kevin Goodsell wrote:
Sander wrote:

... snip ...

But I also think that

if (p == NULL)

is (significantly) easier to read than

if (!p)

I guess this is because 'if (p)' and 'if (p == NULL)' avoid
negatives. Negations (!, !=) tend to be confusing to me -
expressions with fewer negations are usually much easier to
understand.


Another possibility:

#include <iso646.h>
....
if (not p)


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)
if (p==NULL)
if (p!=NULL)
all equally legible. However, I prefer explicit comparison with NULL
when testing a pointer and explicit comparison with 0 when testing
a variable used as an integer (as opposed to a variable used as a
boolean flag). However, I don't feel strongly enough about it to request
others on the projects I am involved in use the same conventions.
--
Flash Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spam, it is real and I read it.
Nov 14 '05 #48

P: n/a
Flash Gordon wrote:
CBFalconer <cb********@yahoo.com> wrote:

.... snip ...

Another possibility:

#include <iso646.h>
....
if (not p)


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".

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #49

P: n/a
On Mon, 22 Dec 2003 20:21:49 UTC, Flash Gordon
<sp**@flash-gordon.me.uk> wrote:
>> assert(p), however, is not (unless you have a C99 compiler).
>
> assert() is ALWAYS a source of confusing the user and destroying
> data consistency!

No, it isn't.


A user who is not a programmer gets a shock, a live crisis if he gets
a screen saying 'core dump' or simply 'trap' or when his GUI program
ends commentless......

assert() is designed to break the program at the point it is called.
This confuses any user - even as it helps any developer to catch
errors s/h/e or her/his colleauge has made.


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.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #50

54 Replies

This discussion thread is closed

Replies have been disabled for this discussion.