Another question related to pointers.

H

Herbert Rosenau

Dear All,

access a memory location until that memory has been allocated either by
assiging the address of a variable
or either through malloc i.e.

ptr = &somevariable;

or

ptr = malloc ( sizeof ( data ) );

However, what I discovered with the following program has made me a bit
uneasy.
Not only can I read the memory pointed to by pointers that still have
not been allocated any
memory, I can write as well.

Can somebody please explain, why pointers p1 and p2 can read from and
read to memory
that they have not been allocated?

Thanks in advance for all your help.

#include <stdio.h>
int main ( void )
{
int *ptr1, *ptr2;

/* Get read access to the memory pointed to by p1 and p2 */
printf ( "*p1 = %d\n", *p1 );
printf ( "*p2 = %d\n", *p2 );

undefined behavior

/* Write to the memory pointed to by p1 and p2 */

*p1 = 1;
*p2 = 2;

again undefined behavior
/* Confirm the write operation */
printf ( "*p1 = %d\n", *p1 );
printf ( "*p2 = %d\n", *p2 );

undefined behavior

return 0;
}

undefined behavior behaves undefined in any possible case. That
includes that it may or may not work as expected either sometimes or
ever or never maybe depending on sunshine or wether, it can produce
maximum damage after showing maximum harmless during debug.....

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
K

Keith Thompson

anonymous said:
You are absolutely alright and I have explained in the other post.

I don't see that other post you referred to, either on my server or on
groups.google.com. (That doesn't imply that you didn't post it, only
that it didn't get through.)

It's not a big deal; if you say it was an honest mistake, I'll take
your word for it.
 
H

Herbert Rosenau

According to the "experts" in this ng, you *can't* write an OS in C.

(This is taking the religious dogma as expressed by some that anything that
isn't "standard C" isn't "C".

You're absolutely wrong. I have written an complete OS using 100% ANSI
C whereas 2% of all were 100% assembly for performance and direct
hardware access. But at least not a single C statement was not ANSI
compilant.

Our quality management had required to use ANSI compilance AND coding
C wherever halfways possible. The 2% NON C was absolutely needed to
get the real work done reliable to make direct hardware access C is
unable to do in any case.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
C

Chuck F.

Herbert said:
You're absolutely wrong. I have written an complete OS using
100% ANSI C whereas 2% of all were 100% assembly for performance
and direct hardware access. But at least not a single C
statement was not ANSI compilant.
.... snip ...
_____________________
/| /| | F
||__|| | Please do not |
/ O O\__ | feed the |
/ \ | Trolls |
/ \ \|_____________________|
/ _ \ \ ||
/ |\____\ \ ||
/ | | | |\____/ ||
/ \|_|_|/ | _||
/ / \ |____| ||
/ | | | --|
| | | |____ --|
* _ | |_|_|_| | \-/
-- _--\ _ \ | ||
/ _ \\ | / `
/ \_ /- | | |
* ___ c_c_c_C/ \C_c_c_c____________

--
"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/>
 
K

Kenny McCormack

According to the "experts" in this ng, you *can't* write an OS in C.

(This is taking the religious dogma as expressed by some that anything that
isn't "standard C" isn't "C".

You're absolutely wrong. I have written an complete OS using 100% ANSI
C whereas 2% of all were 100% assembly for performance and direct
hardware access. But at least not a single C statement was not ANSI
compilant.[/QUOTE]

Thank you for making my case for me. I assume that you meant 98% ANSI C,
as in, "my OS was written in a combination of C and assembler, in an
approximate ratio of 49 to 1".

Then we can consider the matter closed.
 
V

Vadivel

According to my understanding of the program. It will give compilation
error for the pointer variable's p1 and p2, which is not declared in
the given program code.

If you considered that p1 as ptr1 and p2 as ptr2, the happening in the
Enviornment is as follows,

When we declaring a variable (either it is pointer or not pointer ) the
memory will be alloted for that variable in the memory register. While
allocating the memory the Enviornment will store some maximum or
minimum value in that corresponding alocation as a Garbage Value in
accordance to the Data Type.

So, when we refer to the variable it will interrupt the Memory Register
and fetch the value stored in it, because of this process you can able
to execute the program after correcting the variables as ptr1 and ptr2
instead of p1 and p2 respectively.

And also you should remain that the Function Printf will carry only the
memory address of the variable which is passed to it. It won't carry
the values to execute the fuction.

If any one having Controversy in my explain please mail me your
explaination to (e-mail address removed)
 
E

Emmanuel Delahaye

anonymous a écrit :
access a memory location until that memory has been allocated

This is not the point.
either by
assiging the address of a variable
or either through malloc i.e.

This is the point. To be dereferenced, a pointer must hold the address
of a valid memory zone, unless, the behaviour is undefined. Period.
Not only can I read the memory pointed to by pointers that still have
not been allocated any

Of course, it is technically possible to invoke an Undefined Behaviour
(or shot a bullet in your foot), but it's still a bug. Don't do that.
memory, I can write as well.

Can somebody please explain, why pointers p1 and p2 can read from and
read to memory
that they have not been allocated?

A pointer is nothing but a variable. If its content is undefined, or the
address of an undefined memory zone, nasty things are going to happen.
int *ptr1, *ptr2;

/* Get read access to the memory pointed to by p1 and p2 */
printf ( "*p1 = %d\n", *p1 );

what is p1 ? You defined ptr1 ... Please compile before posting. And
don't retype, but copy & paste.
 
E

Emmanuel Delahaye

anonymous a écrit :
That is what I also think i.e. the pointers are pointing to *any*
memory as per garbage
values stored in p1 and p2 and, in turn, garbage value in the pointed
memory is being
accessed.

Don't try to find any logic in an undefined behaviour. Your code is
wrong by construct, fix it and don't waste your time.
 
S

slebetman

Kenny said:
According to the "experts" in this ng, you *can't* write an OS in C.

I know, I know. Don't feed the troll. But let me first say that writing
an OS is what C was originally designed to do.

Was the OS in question (Unix) written entirely in C? Probably not. But
was the 'core' of the OS (the kernel) written entirely in C? Yes. And
before anyone points out that it was not 'standard' C let me point out
that that 'C' was what Dennis Ritchie recognised as C (so at least it
was K&R C). Let me quote Dennis Ritchie on this:

In 1993 Dennis M. Ritchie wrote:
By early 1973, the essentials of modern C were complete. The language
and
compiler were strong enough to permit us to rewrite the Unix kernel
for the
PDP-11 in C during the summer of that year.
( taken from http://cm.bell-labs.com/cm/cs/who/dmr/chist.html )
 
S

slebetman

Kenny said:
According to the "experts" in this ng, you *can't* write an OS in C.

I know, I know. Don't feed the troll. But let me first say that writing
an OS is what C was originally designed to do.

Was the OS in question (Unix) written entirely in C? Probably not. But
was the 'core' of the OS (the kernel) written entirely in C? Yes. And
before anyone points out that it was not 'standard' C let me point out
that that 'C' was what Dennis Ritchie recognised as C (so at least it
was K&R C). Let me quote Dennis Ritchie on this:

In 1993 Dennis M. Ritchie wrote:
By early 1973, the essentials of modern C were complete. The language
and
compiler were strong enough to permit us to rewrite the Unix kernel
for the
PDP-11 in C during the summer of that year.
( taken from http://cm.bell-labs.com/cm/cs/who/dmr/chist.html )
 
R

Richard Bos

I know, I know. Don't feed the troll. But let me first say that writing
an OS is what C was originally designed to do.

That's not how I read that article.
Was the OS in question (Unix) written entirely in C? Probably not. But
was the 'core' of the OS (the kernel) written entirely in C? Yes. And
before anyone points out that it was not 'standard' C let me point out
that that 'C' was what Dennis Ritchie recognised as C (so at least it
was K&R C). Let me quote Dennis Ritchie on this:

In 1993 Dennis M. Ritchie wrote:
By early 1973, the essentials of modern C were complete. The language and
compiler were strong enough to permit us to rewrite the Unix kernel for the
PDP-11 in C during the summer of that year.
( taken from http://cm.bell-labs.com/cm/cs/who/dmr/chist.html )

Note: _re_write. The original Unix was not written in C. And the
original C was not written primarily to write Unix in, but to be used as
a system programming language _under_ Unix.

Richard
 
S

slebetman

Richard said:
That's not how I read that article.


Note: _re_write. The original Unix was not written in C. And the
original C was not written primarily to write Unix in, but to be used as
a system programming language _under_ Unix.

Re-write still means that it was written in C. The "originally"
released Unix (1975) was written in C. All prior versions were written
primarily for internal use (beta?) with very-very limited, if any,
outside distribution.

It is actually not true that C was merely a system programming language
_under_ Unix as Unix itself was written entirely in C. Only some device
drivers and I/O access functions were written in assembly (most of
these functions like getchar and putchar became part of C's stdlib
anyway so it can be argued that they were merely an implementation of
stdlib).

The design of (the original, K&R) C was therefore heavily influenced by
Dennis Ritchie having to write parts of Unix in his own high level
programming language. This is a good thing as they say in the business:
eating your own dog food.
 
W

William J. Leary Jr.

Re-write still means that it was written in C. The "originally"
released Unix (1975) was written in C. All prior versions
were written primarily for internal use (beta?) with very-very
limited, if any, outside distribution.

If your qualifier was "released" (and it seems to be, since you're using 1975
as a date, I assume you mean 6th edition) yes.

But originally UNIX was in B. The "rewrite in C" that I've usually heard about
was in 1973 for the 4th edition.

See http://www.english.uga.edu/hc/unixhistoryrev.html where Ken Thompson is
quoted:

----begin quote----
It was the summer of '69. In fact, my wife went on vacation to my family's
place in California.... I allocated a week each to the operating system, the
shell, the editor, and the assembler, to reproduce itself, and during the month
she was gone, it was totally rewritten in a form that looked like an operating
system, with tools that were sort of known, you know, assembler, editor, and
shell .... Yeh, essentially one person for a month.

The "language" they were writing the OS in was BCPL (Basic Combined Programming
Language)--a tool for compiler writing and systems programming. But in keeping
with their need for extreme economy, Richie wrote a "cut-down version of BCPL"
with the abbreviated name, B.
----end quote----

For the nonce, I could swear that when I heard one of these guys (Ritchie or
Thompson) speak in Boston some ten or fifteen years ago he said that the
original UNIX (or precursor to it?) was in assembler, shortly thereafter
converted to B, but I can find no on-line reference which supports this. I'm
guessing I misunderstood him.

- Bill
 
S

slebetman

William said:
If your qualifier was "released" (and it seems to be, since you're using 1975
as a date, I assume you mean 6th edition) yes.

Actually my qualifier is not "released". It is just that my qualifier
is not "original" either. My beef is with people saying that since the
"original" Unix was not written in C then Unix was not written in C.

That logic does not follow. If Unix was written in C at some point in
its history then it is absolutely true that it "was written in C". Does
not matter which version, all that matters is that it is doable
(remember the days before Unix when people believed that an OS could
not be written in a high level language?). And all that matters is that
it is doable in C which is a reply to Kenny's statement: "According to
the "experts" in this ng, you *can't* write an OS in C".

All I'm saying is that C was designed by Dennis Ritchie at a time when
he was trying to use it to write Unix. So in a real sense, C (at least
the original K&R C) was designed so that you can write an OS in a high
level language.

This all goes back to the original poster complaining that C does not
prevent you from invoking undefined behavior like using an unallocated
pointer. My point is that it is not C's job to 'prevent' you from doing
anything. Warn you, maybe. Prevent you, no. This is because there are
times when the programmer really knows better than the compiler and
really-really want to do dangerous things which is often required when
you are writing an OS. Things like:

int *analog_input = 0x3fff20;
int buffer;
buffer = analog_input;

may be undefined by the C language but may be very well defined by the
target hardware and accompanying documentation.
 
K

Keith Thompson

This all goes back to the original poster complaining that C does not
prevent you from invoking undefined behavior like using an unallocated
pointer. My point is that it is not C's job to 'prevent' you from doing
anything. Warn you, maybe. Prevent you, no. This is because there are
times when the programmer really knows better than the compiler and
really-really want to do dangerous things which is often required when
you are writing an OS. Things like:

int *analog_input = 0x3fff20;
int buffer;
buffer = analog_input;

may be undefined by the C language but may be very well defined by the
target hardware and accompanying documentation.

That code is illegal in modern C, though it was probably ok in the
ancient version of C that was first used to implement Unix. There are
no *implicit* conversions between integers and pointers (other than
the special case of a null pointer constant). And I suspect the last
assignment was meant to dereference the pointer.

In modern C, this would be something like:

int *analog_input = (int*)0x3fff20;
int buffer;
buffer = *analog_input;

You have to be a little more explicit about it, but it still nicely
illustrates the point. The code is highly non-portable, but sometimes
that kind of thing is necessary and appropriate.

I do tend to think that the really dangerous things in C look too much
like the perfectly safe things. In this case, though, the cast should
raise a red flag (most casts are either unnecessary or a sign of
non-portable code). (I've worked in other languages that are far safe
than C by default, but that allow you to get as close to the metal as
you need to if you ask nicely.)
 
K

Keith Thompson

Keith Thompson said:
int *analog_input = 0x3fff20;
int buffer;
buffer = analog_input;

may be undefined by the C language but may be very well defined by the
target hardware and accompanying documentation.
[...]

In modern C, this would be something like:

int *analog_input = (int*)0x3fff20;
int buffer;
buffer = *analog_input;

The first line should probably be

volatile int *analog_input = (int*)0x3fff20;
 
S

slebetman

Keith said:
That code is illegal in modern C, though it was probably ok in the
ancient version of C that was first used to implement Unix. There are
no *implicit* conversions between integers and pointers (other than
the special case of a null pointer constant). And I suspect the last
assignment was meant to dereference the pointer.

In modern C, this would be something like:

int *analog_input = (int*)0x3fff20;
int buffer;
buffer = *analog_input;

Ah yes, that's what I meant. Sorry for the 'bug'.
 
D

Dave Thompson

Re-write still means that it was written in C. The "originally"
released Unix (1975) was written in C. All prior versions were written
primarily for internal use (beta?) with very-very limited, if any,
outside distribution.

It is actually not true that C was merely a system programming language
_under_ Unix as Unix itself was written entirely in C. Only some device
drivers and I/O access functions were written in assembly (most of
these functions like getchar and putchar became part of C's stdlib
anyway so it can be argued that they were merely an implementation of
stdlib).
At least by 6ed I don't believe any drivers were in assembler; they
certainly didn't need to be on the PDP-11, and the ones I looked at
weren't. I didn't go through everything thoroughly but the only
assembler I remember was in system boot (and dump), first-level
interrupt handling which on the -11 includes exceptions and syscall,
trivial wrappings of inter-space access like MT/FPD, and process
switch. (The scheduler _logic_ was in C, including the (in?)famous
comment "you are not expected to understand this", but the actual
switch decided by that logic could not be.)

getchar and putchar were not (AFAIK never) in the kernel. The syscall
interface for everything was read() and write(); for character devices
(drivers) these went directly to the driver (via cdevsw) instead of
going through the block buffer/cache level first.

and 11 Jan 2006 19:41:03 -0800, "(e-mail address removed)"
That logic does not follow. If Unix was written in C at some point in
its history then it is absolutely true that it "was written in C". Does
not matter which version, all that matters is that it is doable
(remember the days before Unix when people believed that an OS could
not be written in a high level language?). <snip>

That was already known (Multics and B6700 at least). What Unix/C
proved was that it could be done for a pretty minimalist design, on a
(then) small/cheap machine, and still be quite useful.

- David.Thompson1 at worldnet.att.net
 
A

anonymous

Dave said:
At least by 6ed I don't believe any drivers were in assembler; they
certainly didn't need to be on the PDP-11, and the ones I looked at
weren't. I didn't go through everything thoroughly but the only
assembler I remember was in system boot (and dump), first-level
interrupt handling which on the -11 includes exceptions and syscall,
trivial wrappings of inter-space access like MT/FPD, and process
switch. (The scheduler _logic_ was in C, including the (in?)famous
comment "you are not expected to understand this", but the actual
switch decided by that logic could not be.)

getchar and putchar were not (AFAIK never) in the kernel. The syscall
interface for everything was read() and write(); for character devices
(drivers) these went directly to the driver (via cdevsw) instead of
going through the block buffer/cache level first.

and 11 Jan 2006 19:41:03 -0800, "(e-mail address removed)"


That was already known (Multics and B6700 at least). What Unix/C
proved was that it could be done for a pretty minimalist design, on a
(then) small/cheap machine, and still be quite useful.

- David.Thompson1 at worldnet.att.net

Many thanks all of you for providing such a detailed explanation anb
*extra* knowledge
for this pointer problem.

Thanks again.
 
J

Jordan Abel

At least by 6ed I don't believe any drivers were in assembler; they
certainly didn't need to be on the PDP-11, and the ones I looked at
weren't. I didn't go through everything thoroughly but the only
assembler I remember was in system boot (and dump), first-level
interrupt handling which on the -11 includes exceptions and syscall,
trivial wrappings of inter-space access like MT/FPD, and process
switch. (The scheduler _logic_ was in C, including the (in?)famous
comment "you are not expected to understand this", but the actual
switch decided by that logic could not be.)

Of course, the code covered by that comment was (based on my reading of
DMR's later explanation of it) ridiculously unportable: relying on an
inappropriate amount of knowledge of compiler internals, specifically,
how the code generated for context-save and return looked in assembler.

http://cm.bell-labs.com/cm/cs/who/dmr/odd.html
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top