"Mastering C Pointers"....

R

Roose

You're playing childish word games again, Richard. (Did I do this
You have correctly misinterpreted a perfectly ordinary and unexceptional
statement as a childish word game. Yes, I think you've more or less got the
right idea.

I know this is pointless, but:

----------------
I wrote:

Let's repeat. "Roose" is not a real person. I, Andy, am a real person.
Roose has not posted here before, but I have.

-------------------
Richard said:
Let's repeat. "Roose" is not a real person.

I guessed as much. Therefore, any article purporting to be from "Roose" is a
forgery, and should under no circumstances be taken seriously. Certainly no
C advice should be accepted from a non-existent person.
I, Andy, am a real person.

Don't call me Andy. It's not my name. And we know it's not /your/ name,
because your name is Roose, and - by your own admission - you don't exist.
Roose has not posted here before, but I have.

You /are/ Roose, and Roose doesn't exist, remember?

-----------------

Children's games, yes? Or you are simply exceptionally obtuse. I think
this one example will suffice, no need to beat a dead horse.

Roose
 
R

Richard Heathfield

Roose said:
Children's games, yes?

Not on my account. I have merely answered to what you've written.

If you say silly things, do you really expect an answer that treats those
silly things seriously? If so, wise up.

If you think I've misinterpreted what you've written, write more clearly in
future.
 
R

Roose

Richard Bos said:
_That_ exact bug? No, obviously not, since Keith already said that that
scenario was a spur-of-the-moment invention. However, some bugs can be
pretty arcane, and only show up under unusual circumstances. For
example, search the Jargon File for "phase of the moon".

For an example where assuming that "integer" is equivalent to "pointer"
leads to a bug, assume that a pointer is six bytes and the best
available integer four.

I'm aware of the pitfalls of assuming pointers are integers. However, I'd
say that when porting non-ANSI code from a platform to where they are
"equivalent" to one where they are not, that you'd simply do well to know
your hardware, and thus this fact would stick out like a sore thumb.
Suppose, also, that for normal users, including developers, their
address space is in the lower part of the spectrum, so that they'll
never encounter the situation where a pointer converted to an integer
overflows, which means that for them, converting a (small) pointer to an
integer and back again apparently works.
Now suppose that your manager, who never uses the program but wants to
demonstrate it to a customer, happens to have a wheel bit set, causing
his address space to be in the upper reaches of memory, which means that
in his case the higher-order bytes of his pointers are _not_ all zero,
unlike the usual case...

I'm not too familiar with wheel bits, but I would suggest that this bug
could quickly found out by any rudimentary testing. Like the manager doing
a dry run before presenting to customers. It depends on the specifics of
course, but I think it is a stretch to think that such errors are likely to
produce rare bugs that could have only been avoided if the code were ANSI C
in the first place.

As I said, I would prefer to incur the cost of portability when the feature
is needed. Not when writing the program for the first device. When porting
to the second device, you will have specific hardware differences to
examine. And then you will incur the cost, and not a particularly great one
in my experience.

Roose
 
R

Roose

Keith Thompson said:
If all the structs are part of a single object (e.g., a single chunk
of memory allocated by malloc()), the kind of thing you describe can
be done portably. For each pointer, cast it to char* and subtract the
base address of the enclosing object to get the byte offset of the
object referenced by the pointer.

Good point.
On the other hand, if it's not practical for all your structs to be
part of the same object (e.g., you want to malloc() them individually)
the kind of mapping and serialization you describe would depend on the
details of how malloc() allocates memory. I don't know enough about
the inner workings of typical heap implementations to know whether
this would be practical, but I suspect there's enough variation to
make it difficult.

You mention subtracting the base address; where does this base address
come from?

Suppose they are all structs of the same type that are stored in an array.
Then the base address would be the address of the first object. The whole
collection would be allocated by a single call to malloc.
If non-portable code really is the best solution for your application,
by all means write non-portable code. Wherever possible, keep it
isolated in a small number of modules, and write the majority of your
application as portably as you can. This will make your job easier
when you need to port it to another platform; the code you have to
modify will be small and contained.

I don't think anybody here has claimed that all C code must be
strictly conforming, or that non-portable code is evil. Non-portable
code is sometimes necessary. But I've found that clean code tends to
be portable, and vice versa. If you develop the right habits, writing
portable code really isn't all that difficult. But when you write
code that depends on the characteristics of a particular system,
you've left the scope of this newsgroup, and if you have any questions
about it, you're more likely to get correct answers in a newsgroup
devoted to that system.

I can agree with that, but my impression is that this reasonable stance is
not the one that the majority of those in this newsgroup take.
Not specifically, but imagine a program that operates on a pointer in
a manner that only works if pointers are just integers. When the
program is ported to a system where that's not the case, it generates
pointer values that point to random locations in memory. If it writes
a value through such a pointer, it can clobber some arbitrary
variable. Sometimes this may be harmless, but sometimes, depending on
the circumstances, the result can be drastic.

I undestand this, but again my contention is that such bugs would be quite
obvious. Code that depends on this simply would not work when ported and
tested for this first time. But as a practical matter, there is a large
percentage of systems (if anyone would like to offer a guess, I would be
interested), where you can assume this.

But my larger point stands, that for pedagogical purposes, it is a useful,
concrete statement to say that a pointer is not unlike an array index. An
integer. Yes there can be other bits set, and so forth. But if you were a
C programmer who was NOT aware of this fact, I would seriously question you.

Roose
 
R

Roose

Richard Heathfield said:
Not on my account. I have merely answered to what you've written.

If you say silly things, do you really expect an answer that treats those
silly things seriously? If so, wise up.

If you think I've misinterpreted what you've written, write more clearly in
future.

Let me ask what is silly about claiming that I have posted in this newsgroup
with different names before.
 
C

Chris Torek

(Yes. Left in just to establish context.)

Above "pairing" fails for "strings", which I believe can attribute for
often mistakes of (mis)handling them (e.g. not allocating memory
for them, or calling strstr() on "binary" data returned from socket,
as can be often? witnessed in questions posted here).
There is only "a value of type 'string'", but no "object of type
'string'". Or am I wrong again?

In C, the term "string" really refers to a data *format*, rather
than anything in the type, value, object, etc., sense.

Suppose I were to tell you that I have a set of (binary) files
in which each "record" is a variable-length region prefixed by
two eight-bit bytes giving the length of the record in big- or
little-endian format (i.e., I tell you which byte to multiply
by 256 before adding the other, to get the length). You then
find the record length by doing:

c1 = getc(fp);
c2 = getc(fp);
if (c1 == EOF || c2 == EOF) ... handle trouble and/or EOF ...
len = c1 * 256 + c2; /* if big-endian */
len = c2 * 256 + c1; /* if little-endian */

Having done this, you can now read the record -- which is "len"
bytes long -- or skip over it using fseek(), for instance.

What I have done is describe a data format for the file. As long
as you have a valid starting point from which to read the file's
records, you can read through all the records in the file, and
detect a "short read" if the file ends too soon (in the middle of
a record, or with c2==EOF but c1!=EOF in the above code).

A C string is just a data format in memory -- simpler than the
record format in this file, because there is no leading count to
interpret, but a data format nonetheless. You could write a sequence
of strings to a binary file and then read them back by reading
bytes until you find each '\0' -- each such set of bytes is a
"string" in the file.
Is string value *and* object at the same time ... ?

Since a string is a data format, you must store it in some other
data object. A sequence of bytes ending with a '\0' will fit in
*any* C object of sufficient size (due to C's requirement that all
objects break down into a sequence of "unsigned char" bytes), but
the most suitable is a sufficiently large array of char (or unsigned
char, in some special circumstances).

Among other things, this means that you can -- nonportably, but
perhaps tested at compile time -- store 7-or-fewer-character C
strings in "double"s, as long as sizeof(double) >= 8 (as is fairly
typical). But you must then use considerable care never to access
those "double"s as lvalues of type "double", since the bit patterns
created by strings might be reserved when treated as ordinary
"double", and cause a runtime trap. (Modern IEEE-fp machines in
particular will trap "signalling NaNs" if the NaN trap is enabled.)
This is thus the kind of code one should only use in an "obfuscated
C" contest.
 
R

Richard Heathfield

Roose said:
Let me ask what is silly about claiming that I have posted in this
newsgroup with different names before.

Well, did you really expect anyone to believe you, after your amazingly
clueless entry into the newsgroup?
 
R

Richard Heathfield

Roose said:
I can agree with that, but my impression is that this reasonable stance is
not the one that the majority of those in this newsgroup take.

Then that majority must be silent indeed, or we'd have heard them, surely?
Keith has very nicely outlined a view which I think /is/ representative of
the majority of regular contributors to this newsgroup.
I undestand this, but again my contention is that such bugs would be quite
obvious.

Alas, this isn't necessarily the case.
Code that depends on this simply would not work when ported and
tested for this first time.

But it might, you see - except in certain, rather odd, situations. I don't
have a specific example on this particular subject, but it is by no means
uncommon for people to write code which /always/ works on Processor A, and
/nearly always/ works on Processor B, despite not being "legal" code. When
this happens, faults on the B version of the code may be few and far
between - but they /do/ happen, and finding them can be a nightmare,
especially since you don't know what you're looking for.
But as a practical matter, there is a large
percentage of systems (if anyone would like to offer a guess, I would be
interested), where you can assume this.

Well, you certainly can't assume pointers are integers on at least three of
the desktop systems in my house.
But my larger point stands, that for pedagogical purposes, it is a useful,
concrete statement to say that a pointer is not unlike an array index.

I agree, provided it is suitably qualified. For example, I like to deal with
this subject using a series of successive "approximations", where it's
clear at each stage that /this/ isn't the right answer, and that one must
read on if one is to get the full picture.

<snip>
 
A

Arthur J. O'Dwyer

Above "pairing" fails for "strings", which I believe can attribute for
often mistakes of (mis)handling them (e.g. not allocating memory
for them, or calling strstr() on "binary" data returned from socket,
as can be often? witnessed in questions posted here).
There is only "a value of type 'string'", but no "object of type
'string'". Or am I wrong again?

I would say, "yes, you're wrong." :) There is no such thing as
a "value of type 'string'," for the simple reason that C doesn't
*have* a type 'string'. What C has is a type 'array of char',
which may under some circumstances *hold* a string.

That is, the "string" is a kind of "meta-value" affected by all
the values of the elements of the char array. If the array
contains a null character, then it contains a "string." But
to avoid confusion [;-)] I do not consider arrays to have "values"
by themselves. The individual *elements* of an array can have
values, and the name of the array certainly has a value when
used in a value context, but the "array" itself... no. Not by
my way of categorizing things.
Is string value *and* object
at the same time and they are just identical, without "dichotomy"
of other types?

char *foo = "hello";
char bar[6] = "world";

'foo' is an object of type 'pointer to char'. Its value is the
address of the first element of the anonymous object "hello", which
itself is of type 'array[6] of char'. 'foo' points to a string.
'bar' is an object of type 'array[6] of char', and its elements
have the values 'w', 'o', [...], '\0' respectively. 'bar' holds
a string.

See, I never once referred to any "object of type string" or
"value of type string," because such things don't exist. There
is no *type* "string" in C.
(That's why I try to avoid to use term "string" when
dealing with C and beginners, unfortunately to the point when
I've recently misleadingly stated /but fortunately was corrected/
that strings don't exist in C

I think (and hope) if you'd said that C doesn't have a string
*type*, you would have been correct. Kind of like C doesn't
have language support for many OOP concepts, but anyone who
flatly claims that you can't do OOP in C will get death-by-
sample-code. :)
<ot> Is there any fitting idiom in English
for that? Something like "falling into one's own trap" ? </ot>).

"Hoist by [one's] own petard." Etymology something involving
dynamite, so I've heard. :)

HTH,
-Arthur
 
R

Roose

Richard Heathfield said:
Well, did you really expect anyone to believe you, after your amazingly
clueless entry into the newsgroup?

Please do not quote out of context, in an attempt to divert the discussion,
as you have made a recent habit of doing. This is irrelevant to the
question at hand, which is whether my argument was logically consistent.
And whether you refused to acknowledge that it was logically consistent by
playing word games with it.

So, let me suggest that you are the one who "resorts to abuse when you run
out of logic". This hypocrisy thing keeps coming back to bite you.

Roose
 
R

Richard Heathfield

Roose said:
Please do not quote out of context, in an attempt to divert the
discussion,
as you have made a recent habit of doing.

Huh? The context I snipped was irrelevant to your question.
This is irrelevant to the
question at hand, which is whether my argument was logically consistent.

Ah. I thought the question at hand was the question you actually asked.
Sorry if I misunderstood you. Okay, is your argument logically consistent?
No.
So, let me suggest that you are the one who "resorts to abuse when you run
out of logic".

How have I abused you, precisely? If you recall, I answered your C question
and politely asked you not to top-post. Since then, I've had nothing but
hostility from you. I think I've been rather patient with you, actually.
This hypocrisy thing keeps coming back to bite you.

I've already admitted that I'm about as hypocritical as the next man. But
let me read between the lines (or line, in this case)... Are you actually
claiming that you, alone of all humans, are free from hypocrisy? Are you
*really* as hypocritical as that? Sorry, but I don't - I /can't/ - believe
it of you.
 
G

goose

Roose said:
Uh, I'm not exactly sure what a symlink is, but if it is anything like a
Windows shortcut, there is definitely an analogy there.

The windows shortcut just stores the location of a file. A "pointer" to it.
An address. The address is the _path name_. In C, the "address" is
basically an integer,

no, it isn't *always* an integer type. in x86 real-mode it is *two*
integer types.
indicating where in a huge array of memory the
variable is.

You can have as many shortcuts as you want that point to the file. A
shortcut takes a small amount of storage, but not as much as a (typical)
file. You can have whole directories of shortcuts that point to files all
over the place, in order to organize them. Likewise, you can have
collections of pointers, that point to various different things _scattered_
all over memory.

For example, on my hard disk, I have a whole bunch of (legal) MP3s organized
by artist and by album. Now, some of them were ripped poorly and have
clicks. So I *could* just copy those files to another folder, in order to
note that I need to rip them again.

However, it is *much* easier and efficient to just copy shortcuts those bad
files into another folder -- called "bad". That way I don't duplicate any
data. And I have all the bad files organized in one directory, and can
access them easily.

You could do the exact same thing with pointers. Suppose I had a whole
bunch of strings in memory, that listed a ton of song names. I could create
an array of pointers called "theBeatles" that pointed to every single song
by the Beatles. Then I could have an array of pointers called "badFiles"
that pointed to all the bad files, _some of which_ may be by the Beatles.
Note that I haven't incurred the storage cost of repeating the strings,
*just* pointers to them. Likewise I could create another array called
"before1960" that points to all songs stored before 1960 -- you get the
idea.

Hm, I'm surprised this didn't come up earlier. This is an easy analogy.

but not entirely accurate. this is because you cannot do "shortcut
arithmetic" but you /can/ do pointer arithmetic.

<to OP>

a pointer variable holds an address of an object. for example
a "pointer to char" can hold the addess of a char, and a
"poniter to int" can hold the address of an int. to access
the object itself, one must dereference the pointer.

dereferencing means "get the object at that address". for example:

/* we declare an object of type int */
int foo = 12;

/* we declare a pointer to int */
int *bar;

/* now we set bar to point to foo, using the address of operator */
bar = &foo;

/* foo still contains 12, while bar contains the address of foo.
now we dereference bar to get the value of foo (namely, 12) */
printf ("bar points to foo which has number %i\n", *bar);
/* that would have printed
"bar points to foo which has number 12."
*/

hth
goose,
busy as can bee
 
R

Roose

This is irrelevant to the
Ah. I thought the question at hand was the question you actually asked.
Sorry if I misunderstood you. Okay, is your argument logically consistent?
No.

Let's hear a reason for this, please. My assertion is that I have posted
here before, but not under the handle Roose.

What, exactly, is "silly" about this, regardless of its truth. I know you
doubt me, as you have stated, but you can simply say so (and you did). But
instead you chose, embarassingly, to try to debunk my argument with a series
of silly statements yourself. Like the fact that I must be "non-existent",
etc. and similar blabber.
I've already admitted that I'm about as hypocritical as the next man. But
let me read between the lines (or line, in this case)... Are you actually
claiming that you, alone of all humans, are free from hypocrisy? Are you
*really* as hypocritical as that? Sorry, but I don't - I /can't/ - believe
it of you.

Wow, Richard is reading between the lines finally! But no, I make no such
claim of myself, only that you have obviously been a hypocrite.
 
C

Chris Torek

Chris Torek said:
For something really different, I would suggest trying [list of
"different" machines]

Shouldn't the HP3000 running MPE fit in there somewhere? I
believe it just became unsupported. Many Burroughsisms. It DID
have a C compiler 25 years ago.

Well, 25 years ago was 1987, which predates ANSI C, but mainly I
did not list it because I never used it nor even read much about
it. (I have not used the AS/400 either, but I have read a bit from
those who have.) I think certain Tandem machines might also fit
in the "oddball" category.

Another good example is the Cray vector machines (T90, SV1, et al).
As far as the C compiler is concerned, bytes are 8 bits, but all
integer types other than the char types are 64 bits. Native addresses
point to 64-bit words. A byte pointer is formed by storing a 3-bit
byte offset in the high-order bits of a 64-bit word pointer.

As I recall from discussions long ago on comp.std.c, this was just
one of two ways to handle "byte pointers" on Crays. (The other
was Eclipse-style shifting for pointer conversions. Perhaps this
method was used on different hardware.)
Pointer arithmetic works just fine, but I've seen non-portable
code that tried to do arithmetic on a pointer by casting it to an
integer type, performing integer arithmetic on it, and casting it
back. It didn't work.

Indeed. However, the AS/400 covers this same case in what I think
is a more eye-opening manner: performing such pointer arithmetic
tricks results in a pointer that traps when used, and perhaps in
some cases, even when simply assigned. (The reason is that the
"capability" portion of the pointer -- the part that determines
access permissions -- simpy disappears, so you are left with an
invalid pointer, even if it has the right "value" bits.)
 
G

goose

Irrwahn Grausewitz said:
Apparently he's both, see below.


I had some spare time and did a quick google groups search. If you're
only interested in the highlights, do a search for threads that have his
name in the _subject-line_. For the full load perform a search for
articles he posted. It's real fun.

and the choicest flame ever award (and to save others the trouble of
googling) goes to Pierre Honeyman:

---------------------------------------------------------------------------
From: Pierre Honeyman ([email protected])
Subject: Alan Connor, Uber-Idiot

View: Complete Thread (3 articles)
Original Format

Newsgroups:
rec.martial-arts
Date: 2003-11-04 15:44:59 PST

It's the latest entry into RMAs ongoing TrollMatch.

A man who has taken the whole "Hate America First" extremism to a
whole new level. A man who has decided to just hate the whole human
race, because wolves are obviously smarter and more humane. A man who
can afford a computer, a phone line, and an internet account on
$200/year - in the US. A man so powerful in the mighty art of Tai
Chen (which he's studied for a whole year now) that he is invulnerable
to either the sword's stab or the hunter's bullet. A man so righteous
that his killfile causes pain. A man so omnipotent that he will reply
to people *he has already killfiled*.

It's Alan Connor.

He's a strong entry in an already strong field. Competing against
well established entrants, he'll have to stick around to really score
some points with the more cynical judges, but his opening moves have
been well received by all.

Will he be able to maintain his formidable momentum? Only time will
tell.

He's a well known idiot in other groups, but can he make it here?

Pierre

---------------------------------------------------------------------------

the sad part is that "roose" is only one letter away from "goose" :-(

(btw: "roose" is an intentional troll, ever considered that
"roose" is just a mispelled "ruse"?)
I still don't think so.


And miss the fun? Naw...

i should have read the whole thread through before trying to
be helpfull. I've wasted precious time today.

goose,
the non-troll type
 
N

Nils Petter Vaskinn

You mean the time RJH told Dennis Ritchie he (DMR, not RJH) was off
topic? Yes, that really happened.

Is that archived somewhere? Google? Somewhere else?
 
K

Keith Thompson

Roose said:
I can agree with that, but my impression is that this reasonable stance is
not the one that the majority of those in this newsgroup take.

Actually, I believe it is. Anyone who disagrees should feel free to
jump in.

[...]
I undestand this, but again my contention is that such bugs would be quite
obvious. Code that depends on this simply would not work when ported and
tested for this first time. But as a practical matter, there is a large
percentage of systems (if anyone would like to offer a guess, I would be
interested), where you can assume this.

No, in real life, such bugs are often not obvious. Vendors release
patches for software bugs all the time. What do you think causes
those bugs? And why do you think they weren't found in testing before
the software was released in the first place?
But my larger point stands, that for pedagogical purposes, it is a useful,
concrete statement to say that a pointer is not unlike an array index. An
integer. Yes there can be other bits set, and so forth. But if you were a
C programmer who was NOT aware of this fact, I would seriously question you.

A C programmer should be aware that pointers are represented as
integers on many systems, and are represented similarly to integers on
many others, but he should be able to write code that doesn't depend
on this knowledge. As several of us have said, writing portable code
can actually be easier than writing gratuitously non-portable code.

You yourself gave an example of a program that you said depends on the
non-portable assumption that pointers are represented as integers
(serializing data by converting pointers to numeric offsets before
writing out a data structure). I demonstrated how the same thing
could be done just as easily in portable C, using only the properties
of pointers defined by the language. The solution I outlined would
work even on the unusual systems we've been discussing with bizarre
pointer representations.
 
I

Irrwahn Grausewitz

Keith Thompson said:
Does this refer to Richard or to me?

Err, damn, no, neither! I managed to forget to mention the name of the
individual in question: Alan Conor.
Did you ever abuse usenet in a manner that would make it worth to do a
google search? Can't imagine that. :)

Regards
 

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

Forum statistics

Threads
474,303
Messages
2,571,559
Members
48,361
Latest member
arunkumar00
Top