pointers and integers

M

Mark McIntyre

On 2 Jun 2005 06:40:42 -0700, in comp.lang.c ,
In embedded systems, some of the processor registers are memory mapped.
I have seen certain piece of code, where these registers are accessed
in this manner.

All this might well be true.
This might not be the correct way of doing it.
In such scenarios, how these registers should be accessed ?

There's no 'correct' way. The standard doesn't require this conversion
to be meaningful, although an implementor is free to provide a
meaning. So...
Or the only way is to read the compiler's documentation

.....this is indeed the only way to know if your particular hardware /
os / compiler supports the conversion.
 
K

Keith Thompson

In embedded systems, some of the processor registers are memory mapped.
I have seen certain piece of code, where these registers are accessed
in this manner. This might not be the correct way of doing it.
In such scenarios, how these registers should be accessed ?
Is there a better way of doing it ? Or the only way is to read the
compiler's documentation to find out how it deals with integer/pointer
conversion as pointed out by "pete" in this thread earlier.

In portable standard C, conversions between integers and pointers are
permitted but meaningless (except for a few statements about null
pointer constants and conversions back to the original type).

In non-portable C, the implementation is allowed to make whatever
additional guarantees it likes, as long as they don't conflict with
the standard. An implementation can even define the behavior of
something that invokes undefined behavior according to the standard.

So, if you happen to know that 0x100 is a valid address on your
system, and that casting the integer value 0x100 to a pointer type
will get you a valid pointer to that address, and that you're allowed
to read a byte value from that address, then this:

unsigned char *ptr = (int*)0x100;
unsigned retrieved_value = *ptr;

or, equivalently, this:

unsigned char retrieved_value = *(unsigned char*)0x100;

is the right way to retrieve that value. (Better yet, define a macro
with a meaningful name that expands to 0x100; magic numbers are bad
style even in embedded systems.)

There's nothing inherently sinful about writing non-portable code when
it's appropriate. Some suggested rules for non-portable code:

Don't do it unless it's necessary. If you can do something portably,
do so -- unless there's some real advantage (like *substantially*
better performance) to the non-portable solution.

Be aware that it's non-portable. If you need to port the code to
another platform, expect to spend some extra time re-writing the
non-portable portions. Don't assume that it's going to work just
because it compiles; reading from location 0x100 might initiate the
self-destruct sequence on another system.

Keep the non-portable and portable portions of your code separated as
much as possible. For example, restrict the non-portable code to a
single module (e.g., associated .h and .c files). If you port the
code to another platform, you only need to rewrite that one module.

Don't expect to discuss the details here in comp.lang.c. The
existence of non-portable code is topical; the details of how it works
generally are not, except in the context of discussing the general
principles of the language.
 
G

glen herrmannsfeldt

Wrong. RTBS.
You can always _cast_ any integer to any kind of pointer, regardless of
their sizes. However, the result need not even be a valid pointer value,
so you can't rely on being able to use it for anything; even assignment
to a pointer variable can cause undefined behaviour.

If I remember it right, there is some qualification related to knowing
how the underlying machine works. On systems where pointers are
addresses, and where the hardware allows assignment between pointers and
integers it should work. The hardware isn't required to allow that, and
pointers are not required to be plain addresses.

JVM does not allow assignment between pointers (object references) and
integers. There are likely other machines that also disallow it.

-- glen
 
R

Richard Bos

glen herrmannsfeldt said:
If I remember it right, there is some qualification related to knowing
how the underlying machine works.

Not really. There's a footnote that the result is "intended to be
consistent with the addressing structure of the execution environment",
but it's only a footnote. The main text says nothing more than that the
result is implementation-defined.
Interestingly enough, C99 is stricter than C89; C89 makes the result
implementation-defined, but C99 adds the explicit warning that it might
not be properly aligned or point at anything.

Richard
 

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
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top