pointer q

C

CBFalconer

Joe said:
"Flash Gordon" <[email protected]>
.... snip ...


He sounds like a dude, so you can be assured that I won't give
him face, but until otherwise motivated, I'll give him the benefit
of the doubt. Thanks for your reply. Joe

That's your prerogative. However the more the troll is ignored,
the better the likelihood that it will go away and stop consuming
resources, thus some of us like to point out the conclusions
reached earlier.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
F

Flash Gordon

Joe said:
Flash Gordon said:
Joe said:
[snip]
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */
This is very different. If you were trying to fix the code further up so
it would compile what you wanted was:
short *sp = (short*)*lp; /* ill-advised, but Let's Pretend */
How thick is my head ^ ?

We all make mistakes.

Am I not reading, with correction, the number that a smaller type thinks a
larger type was? My socks are well accounted for, but Scott Knuds not only
flew out of my hard drive, but is eating my lunch.

Your version of the code:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.

My partial correction:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp = (short)*lp; /* ill-advised, but Let's Pretend */

/* Use of *sp */

Tries to read a short from where a long was stored. On normal 2s
complement systems the part of the long that is read will depend on the
endianness of the system.

The standard also says:
| An object shall have its stored value accessed only by an lvalue
| expression that has one of the following types:74)
| — a type compatible with the effective type of the object,
| — a qualified version of a type compatible with the effective type of
| the object,
| — a type that is the signed or unsigned type corresponding to the
| effective type of the object,
| — a type that is the signed or unsigned type corresponding to a
| qualified version of the effective type of the object,
| — an aggregate or union type that includes one of the aforementioned
| types among its members (including, recursively, a member of a
| subaggregate or contained union), or
| — a character type.
I.e. don't do what the above code does.

It is also possibly in general (though unlikely in this specific case)
for short to have trap representations. If the part of the long that is
read as a short happens to be a trap representation for short (e.g. -0
on a 1s complement system where -0 is a trap) then you have again
invoked undefined behaviour.

The comments about ridiculous things happening are just to make the
point that the C standard does not care what happens, so anything your
compiler does, including something completely unexpected
He sounds like a dude, so you can be assured that I won't give him face, but
until otherwise motivated, I'll give him the benefit of the doubt. Thanks
for your reply. Joe

Your choice. Just don't expect any errors in its posts to be corrected.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
J

Joe Smith

Flash Gordon said:
Joe said:
Flash Gordon said:
Joe Smith wrote: [snip]
*sp = (short)*lp; /* ill-advised, but Let's Pretend */
This is very different. If you were trying to fix the code further up so
it would compile what you wanted was:
short *sp = (short*)*lp; /* ill-advised, but Let's Pretend */
How thick is my head ^ ?
We all make mistakes.
See below.
Your version of the code:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.

My partial correction:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp = (short)*lp; /* ill-advised, but Let's Pretend */
It's a little hard to discern what is a mistake when the premise is that
what we're doing is ill-advised or illegal. I do think the above line is
miscast.

/* Use of *sp */

Tries to read a short from where a long was stored. On normal 2s
complement systems the part of the long that is read will depend on the
endianness of the system.

The standard also says:
| An object shall have its stored value accessed only by an lvalue
| expression that has one of the following types:74)
| — a type compatible with the effective type of the object,
| — a qualified version of a type compatible with the effective type of
| the object,
| — a type that is the signed or unsigned type corresponding to the
| effective type of the object,
| — a type that is the signed or unsigned type corresponding to a
| qualified version of the effective type of the object,
| — an aggregate or union type that includes one of the aforementioned
| types among its members (including, recursively, a member of a
| subaggregate or contained union), or
| — a character type.
I.e. don't do what the above code does.
I think if a fellow were serious, ie, trying not to do illegal or
ill-advised things, and he wanted to "pick apart" something that the
compiler has stored as a long at an address accessible to the source, he
would go after it with the last of those options, unsigned chars, and make
the necessary conversions to make zeroes and ones.
It is also possibly in general (though unlikely in this specific case) for
short to have trap representations. If the part of the long that is read
as a short happens to be a trap representation for short (e.g. -0 on a 1s
complement system where -0 is a trap) then you have again invoked
undefined behaviour.
Writing to something unitialized is going to be trouble every day of the
week, but again, I would say unsigned chars are the safest way to go.

The comments about ridiculous things happening are just to make the point
that the C standard does not care what happens, so anything your compiler
does, including something completely unexpected
Easy for you to say! Mr Knudds ate my reuben on rye.

[snip]
As to trolls, I don't know enough about the phenomenon to fill a sacrament
cup. I've witnessed enough dehumanizing to have no pallette for it.

There's something driving me bats right now. How does one complete this
table:

long * | short | long ***
-------------------------------------------------
type is | | |
----------------------------------
type-specifier is | | |

Thanks for your time. joe
 
F

Flash Gordon

Joe said:
Flash Gordon said:
Joe said:
"Flash Gordon" <[email protected]>
Joe Smith wrote: [snip]
*sp = (short)*lp; /* ill-advised, but Let's Pretend */
This is very different. If you were trying to fix the code further up so
it would compile what you wanted was:
short *sp = (short*)*lp; /* ill-advised, but Let's Pretend */
How thick is my head ^ ?
We all make mistakes.
See below.
Your version of the code:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.

My partial correction:
#include <stdio.h>

int main ( void )
{long l = 420000;
long *lp = &l;

short *sp = (short)*lp; /* ill-advised, but Let's Pretend */
It's a little hard to discern what is a mistake when the premise is that
what we're doing is ill-advised or illegal. I do think the above line is
miscast.

Arrrgggghhh!
I meant
short *sp = (short*)lp; /* ill-advised, but Let's Pretend */
I think if a fellow were serious, ie, trying not to do illegal or
ill-advised things, and he wanted to "pick apart" something that the
compiler has stored as a long at an address accessible to the source, he
would go after it with the last of those options, unsigned chars, and make
the necessary conversions to make zeroes and ones.

Yes, using unsigned char would be the correct way to pick it apart, and
indeed there are sometimes good reasons for doing this.. You still have
to watch out for endianness and be aware that different implementations
have different length longs.

There's something driving me bats right now. How does one complete this
table:

long * | short | long ***

You should really use a fixed width font when doing things like tables.
It may have looked formatted on your machine, but here it looks a right
mess, and I'm not going to try all my fonts on the off chance one uses
the same spacings as whatever font you used.

The type specifiers in the above are short and long. The types are
long*, short and long***.

You might find a copy of the latest draft of the C standard useful, see
http://clc-wiki.net/wiki/C_standard
Section 6.7.2 is called "Type specifiers" and obviously tells you what
they are!
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
C

CBFalconer

Joe said:
.... snip ...

There's something driving me bats right now. How does one complete
this table:

long * | short | long ***

That doesn't look anything like a table here. I suspect you are
using some sort of proportional font, which doesn't do well over
usenet. Use a fixed font. A clearer version:

long * | short | long ***
-------------------------------------------------
type is | pointer to long | short | ptr to ptr to
| | | ptr to long
-----------------------------------------------
type-specifier is | long *item | short item | long ***item

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
J

Joe Smith

Flash Gordon said:
Joe said:
"Flash Gordon" <[email protected]> [ill-advised and illegal stuff]
short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.
Is it the miscast here that creates the unitialized pointer?
Yes, using unsigned char would be the correct way to pick it apart, and
indeed there are sometimes good reasons for doing this.. You still have to
watch out for endianness and be aware that different implementations have
different length longs.
It seems to me that indeed this would be a way to discern endianness.
You should really use a fixed width font when doing things like tables. It
may have looked formatted on your machine, but here it looks a right mess,
and I'm not going to try all my fonts on the off chance one uses the same
spacings as whatever font you used.

The type specifiers in the above are short and long. The types are long*,
short and long***.
Crap, I was really proud of that, using only the space bars for spaces and
explicit carriage return. Alles klar on the answer. joe
 
F

Flash Gordon

Joe said:
Flash Gordon said:
Joe said:
"Flash Gordon" <[email protected]> [ill-advised and illegal stuff]
short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.
Is it the miscast here that creates the unitialized pointer?

No, the fact that you have not assigned a value to sp yet you are
assigning to *sp does it. Where do you think sp points?
It seems to me that indeed this would be a way to discern endianness.

<snip>

Yes, given known values. However, there are middle endian systems as
well as big and little endian...
 
J

Joe Smith

Flash Gordon said:
Joe said:
Flash Gordon said:
Joe Smith wrote:
"Flash Gordon" <[email protected]>
[ill-advised and illegal stuff]
short *sp;
*sp = (short)*lp; /* ill-advised, but Let's Pretend */

Writes through an uninitialised pointer which is undefined behaviour.
Is it the miscast here that creates the unitialized pointer?

No, the fact that you have not assigned a value to sp yet you are
assigning to *sp does it. Where do you think sp points?
sp points to the code I had in my head, not the source to which I replied.
<snip>

Yes, given known values. However, there are middle endian systems as well
as big and little endian...
I was unaware of 'middle' as an endianess. Does C care how an
implementation represents, e.g. a long?
 
J

Joe Smith

"CBFalconer"
Joe Smith wrote:

That doesn't look anything like a table here. I suspect you are
using some sort of proportional font, which doesn't do well over
usenet. Use a fixed font. A clearer version:

long * | short | long ***

Does this show a show a diagonal line of numbers:

1234567890
2
3
4
5
6
7
8
9
0
? joe
 

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
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top