a little mistake

R

Richard Heathfield

Kenny McCormack said:
This is an argument you can't possibly win here. It's too sensible.

See, the problem is, you've positioned yourself as a reasonable person,
interested in theory, but practical as well. And, presumably, *not*
suffering from Asperger's.

http://en.wikipedia.org/wiki/Aspergers

It is evident that you are not qualified to diagnose Asperger's Disorder,
because if you were, you would not trivialise it in this way. It is
disquieting that "Asperger's" is becoming a term of abuse aimed at people
who care about correctness, especially so since it can only serve to debase
the term, making it more difficult for physicians to use it dispassionately
to describe those who actually do suffer from it. I am no physician, of
course, but I do know someone - a young child - who really does suffer from
Asperger's Disorder, and I can assure you that it is not a subject for
humour. To use the term as an insult is beneath contempt.
See, the basic structure of this ng allows for two classes: "newbies"
(aka, cannon fodder) and "regulars". You (and I) fit into neither
category. I have recently coined the term "observers" for us.

There are people here who seek high quality help in C programming. There are
people here who provide high quality help in C programming. And then there
are those who, like you, provide nothing but criticism of those who help.
These last are a constant drain on clc's resources, and the group would be
far better off without them.

Instead of continually making a fool of yourself, why not roll your sleeves
up and pitch in to the task of helping people out with high quality C
advice? Or is that too difficult for you?
 
R

Richard Heathfield

CBFalconer said:
Making that assumption, in any case where it may matter, is
extremely sloppy programming.

if(0 == NULL)
{
puts("No, it's guaranteed that 0 == NULL.");
puts("This stuff will always be written to stdout.");
}
 
K

Kenny McCormack

Making that assumption, in any case where it may matter, is
extremely sloppy programming.

I don't see where you get "extremely" out of this. There is a quote,
attributed to Mark Twain, that goes like this:

Every place where you use the word "very", you should substitute "damn".
Your editor will remove them all, and your writing will be better for it.

I think that goes for most of the silly superlatives used in this ng.

Also, as noted elsethread, there is a difference between asserting that
when we write:

0 == NULL

in a conforming C program, we might as well write:

1

(or whatever other representation of "true" you are comfortable with),
that's not the same as asserting that NULL is all bits zero.

(For whatever that's worth...)
 
T

Tom St Denis

Richard said:
CBFalconer said:


if(0 == NULL)
{
puts("No, it's guaranteed that 0 == NULL.");
puts("This stuff will always be written to stdout.");
}

Assuming he meant "all-zero == NULL" he's wrong anyways. It won't
raise a bug on platforms where NULL != all-zero, since NULL can never
be a valid pointer anyways.

So while it's true on some imaginary [or just plain old and non viable]
platforms NULL is not "all-zero", it is on many and it DOES in fact
result in bugs being caught. So it's at worst "redundant" and at best
a time saver.

In terms of correctness the poster who suggested initializing all
pointers to NULL was correct. Ideally that's the proper way to code.

Irrespective of HOW you make the allocated data [calloc or proper init]
you should still NULL check pointers.

Tom
 
F

Frederick Gotham

Richard Bos posted:
The Standard. Uninitialised is uninitialised is not guaranteed any
value _or_ non-value.


That's what I wrote. Allowed - not required - to be neither. I didn't
write "not allowed to be either".


Sorry, that's the second time today I muddled up the English language...
I made a similar mistake on comp.lang.c++ within the last hour. Consider
when someone asks:

Would you like tea or coffee?

Sometimes you expect a response of "yes" or "no", and other times you
expect "tea" or "coffee".
 
K

Kenneth Brody

Frederick Gotham wrote:
[...]
Sorry, that's the second time today I muddled up the English language...
I made a similar mistake on comp.lang.c++ within the last hour. Consider
when someone asks:

Would you like tea or coffee?

Sometimes you expect a response of "yes" or "no", and other times you
expect "tea" or "coffee".

"Excuse me... Do you know what time it is?"

And, if you ask a computer for a list of clients in New York and
California, you'll probably get a very small (if not empty) set.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
C

CBFalconer

Tom said:
I'd actually like you to point out the market share of platforms
where (void*)0 Isn't for all intents and purposes equal to NULL.

It is, by definition in the standard. However a pointer object
with all bits 0 is not necessarily a NULL, as Richard has tried to
explain.
 
C

CBFalconer

Richard said:
CBFalconer said:

if (0 == NULL)
{
puts("No, it's guaranteed that 0 == NULL.");
puts("This stuff will always be written to stdout.");
}

Yes, I was sloppy. That is a zero constant in a pointer context.
 
C

CBFalconer

Tom said:
.... snip ...

In terms of correctness the poster who suggested initializing all
pointers to NULL was correct. Ideally that's the proper way to code.

Irrespective of HOW you make the allocated data [calloc or proper
init] you should still NULL check pointers.

You still don't seem to have grasped the point that callocing
something including pointers does not make those pointers NULL.
 
K

Keith Thompson

Tom St Denis said:
I'd actually like you to point out the market share of platforms where

(void*)0

Isn't for all intents and purposes equal to NULL.

There are none, since (void*)0 is by definition a null pointer
constant. It's guaranteed by the language to yield a null pointer of
type void*, regardless of how a null pointer happens to be
represented.
And more importantly,

memset(&mypointer, 0, sizeof(void*))

Doesn't produce NULL in mypointer. I know it's not STANDARD. It's
just REALLY REALLY REALLY common.

I agree that it's really really really common for null pointers to be
represented as all-bits-zero. There's nothing wrong with code that
happens to take advantage of this (more on that point below), as long
as it doesn't depend on the assumption.

Code that *assumes* that a null pointer is all-bits-zero will probably
happen to work on most existing platforms (if it doesn't also assume,
as such code often does, that all pointers are the same size, or that
pointers are the same size as int) -- but it's still incorrect, and it
will fail if executed on a rare platform where null pointers aren't
all-bits-zero.

Properly written code that *doesn't* assume that a null pointer is
all-bits-zero (or that all pointers are the same size, or that
pointers are the same size as int) will work correctly regardless of
the representation of a null pointer. In particular, it will continue
to work correctly years from now when somebody recompiles it on some
future exotic platform that uses all-bits-one to represent null
pointers. And since it's just as easy to write code that doesn't make
this assumption as to write code that does, there's really no excuse
for writing non-portable code in the first place -- even if it happens
to work on the limited set of platforms you happen to use.
It isn't the reason I check for NULL though.
Good.

[...]

When you calloc a structure with pointers, they're VERY LIKELY to be
equal to NULL. this is the "added bonus" I was talking about. As in,
in addition to the original purpose of the check.

When you calloc a structure with pointer, it's VERY LIKELY that the
author assumed that null pointers are always represented as
all-bits-zero. The author is likely to have made other incorrect
assumptions as well.

It's simple, really: Don't calloc structures with pointers. (Or at
least don't calloc structures with pointers and assume that the
resulting pointers will be null.)

Checking a pointer parameter against NULL (assuming NULL is an invalid
value) is a good idea, assuming you have a decent way to handle the
error. If uninitialized variables happen to be all-bits-zero more
often than not, and if null pointers happen to be all-bits-zero on the
current platform, then this will catch *some* cases of uninitialized
pointers in addition to catching pointers that are being misused after
having been initialized to NULL. I'll grant you that this is a small
bonus (but a very unreliable one).

It's perfectly true that null pointers are all-bits-zero on most
(nearly all?) current platforms. The problem is, too many people use
that fact as a basis for arguing that it's ok for code to *assume*
that null pointers are all-bits-zero. I don't *think* that's what
you're arguing, but someone who reads your articles with insufficient
care might draw that conclusion.
 
O

Old Wolf

Tom said:
When you calloc a structure with pointers, they're VERY LIKELY to be
equal to NULL. this is the "added bonus" I was talking about.

#include <stdio.h>
#include <stdlib.h>

int main()
{
if ( rand() % 12345678 == 7654321 )
printf("tom is an egg\n");

return 0;
}

It's VERY LIKELY that this program will never offend anyone
when run. Does that make it acceptable?
 
D

Dave Thompson

The following technique has served me well when creating aggregate objects
of type T:

#include <stdlib.h>
#include "t.h"

T *T_create(int this, double that, long theother)
{
const T blank = {0};
I declare this static. Although a good enough compiler could figure
that for me, it's easy enough not to assume/rely on that.
T *new = malloc(sizeof *new);
if(new != NULL)
{
*new = blank; /* get default static initialisers in place */
new->this = this;
new->that = that;
new->theother = theother; /* override specific fields */

/* all other fields in 'new' have their default values */
}
return new;
}

This way guarantees that *either* the allocation fails (in which case 'new'
is NULL) *or* it succeeds and no member object of 'new' will be
uninitialised.

Alternatively, I might soon start using C99 *new = {.this = etc.} .


- David.Thompson1 at worldnet.att.net
 
F

Frederick Gotham

Dave Thompson posted:
I declare this static. Although a good enough compiler could figure
that for me, it's easy enough not to assume/rely on that.


I would think that that would be misuse of the "static" keyword.

The purpose of static variables within functions is that we can retain a
value until the next invocation of that function.
 
C

Chris Dollin

Frederick said:
Dave Thompson posted:


I would think that that would be misuse of the "static" keyword.

Why? `static` says there's just the one `blank`, rather than a new
`blank` each function call. That seems to be just fine.
The purpose of static variables within functions is that we can retain a
value until the next invocation of that function.

That's not /the/ purpose. That's /a/ purpose. Another purpose is to
hide a constant from sibling functions.
 

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
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top