Lowest addressed character in array

A

arnuld

They *require* that the argument (for example, the argument to strlen())
is a pointer to a string.

The idea that a null pointer is not a pointer to a string is implicit in
the Standard's definition of the phrase "pointer to a string" (C99
7.1.1p1).

Just checked it out and its says:

"A pointer to a string is a pointer to its initial (lowest addressed)
character."


Here is what I get:

#include <stdio.h>

int main(void)
{
const char* arrc = "clc";
const char* p = arrc;

for(; *p; ++p)
{
printf("p: %p\n", (void*)p);
}

return 0;
}
================ OUTPUT ========================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra test.c
[arnuld@dune programs]$ ./a.out
p: 0x80484b0
p: 0x80484b1
p: 0x80484b2
[arnuld@dune programs]$


of course, lowest adressed character is first one, element on index
zero). I remember one of my colleagues telling me that array elements
need not be in ascending order of addresses, they can be in descending
order of addresses e.g. in my example, it could print 4b2, 4b1, 4b0.
There is not guarantee that elements are always laid down in ascending
order in RAM (memory). From what you say I think he was wrong (if I get
correctly what Standard say). Any enlightenment here ?


There's no need for strlen() to make that distinction itself. It's
entirely the responsibility of the caller, just as it's the caller's
responsibility not to call strlen() with a pointer that's just been
free()'d.

A pointer value may be valid or invalid depending on the context in
which it's used. A null pointer value is perfectly valid on the RHS of
an assignment, but not as the operand of a unary "*". A pointer to a
struct object that's been converted to void* is valid as an argument to
memset(), but not as an argument to strlen().

I suppose that having string functions treat null pointers as if they
were pointers to empty strings would be more convenient in some cases
(though it could impose extra overhead where the caller has taken care
to pass a non-null pointer), but in my opinion it makes for a more
consistent mental model.

If you had a function that took an int* argument, would you want it to
treat a null pointer as if it pointed to an int with the value 0?

Admittedly, the difference there is that you can pass int arguments
directly, so there's no need to use a pointer if you just want the
value. If C were able to treat strings as first-class objects (as some
languages do), we probably wouldn't be having this debate.
 
K

Keith Thompson

arnuld said:
They *require* that the argument (for example, the argument to strlen())
is a pointer to a string.

The idea that a null pointer is not a pointer to a string is implicit in
the Standard's definition of the phrase "pointer to a string" (C99
7.1.1p1).

Just checked it out and its says:

"A pointer to a string is a pointer to its initial (lowest addressed)
character." [...]
#include <stdio.h>

int main(void)
{
const char* arrc = "clc";
const char* p = arrc;

for(; *p; ++p)
{
printf("p: %p\n", (void*)p);
}

return 0;
}
================ OUTPUT ========================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra test.c
[arnuld@dune programs]$ ./a.out
p: 0x80484b0
p: 0x80484b1
p: 0x80484b2
[arnuld@dune programs]$


of course, lowest adressed character is first one, element on index
zero). I remember one of my colleagues telling me that array elements
need not be in ascending order of addresses, they can be in descending
order of addresses e.g. in my example, it could print 4b2, 4b1, 4b0.
There is not guarantee that elements are always laid down in ascending
order in RAM (memory). From what you say I think he was wrong (if I get
correctly what Standard say). Any enlightenment here ?
[...]

Addresses of successive element of an array are always guaranteed
to be in increasing order, but "increasing" is defined in terms of
pointer operations: &p[1] > &p[0], &p[2] > &p[1].

The hexadecimal values you're seeing are a printable *representation*
of the addresses; they're not the addresses themselves. Remember,
addresses (pointer values) are not integers -- though they can
be converted to integers (the result of such a conversion should
normally be consistent with the addressing structure of the machine),
and are very often implemented as bit patterns that behave like
integers.

There is no guarantee that the output of your program will even look
like a sequence of integers; it could legally be:

p: red
p: green
p: Wednesday

(though that's almost fantastically unlikely).

Strictly speaking, your colleage is right; practically speaking, he's wrong.
 
S

Seebs

of course, lowest adressed character is first one, element on index
zero). I remember one of my colleagues telling me that array elements
need not be in ascending order of addresses, they can be in descending
order of addresses e.g. in my example, it could print 4b2, 4b1, 4b0.

Uh, no.
There is not guarantee that elements are always laid down in ascending
order in RAM (memory). From what you say I think he was wrong (if I get
correctly what Standard say). Any enlightenment here ?

Why do you listen to these people?

-s
 
N

Nick

Seebs said:

In "angels on the head of a pin mode", as there is nothing other than an
implementation defined way to convert a pointer to an integer:
a) it could /print/ 4b2, 4b1, 4b0 even if they were ascending up the
memory (I'm pretty sure of this one) - ie, %p could just subtract the
actual pointer address from all-1s.
b) (I'm slightly less sure). If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.
 
K

Keith Thompson

Nick said:
In "angels on the head of a pin mode", as there is nothing other than an
implementation defined way to convert a pointer to an integer:
a) it could /print/ 4b2, 4b1, 4b0 even if they were ascending up the
memory (I'm pretty sure of this one) - ie, %p could just subtract the
actual pointer address from all-1s.

Agreed -- except that %p converts a pointer to a string, not
(necessarily) to an integer.
b) (I'm slightly less sure). If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.

I think pointers would have to keep track of the size of the blocks
they're pointing to. For example, given char arr[100], &arr, in
your model, points to the end of the 100-byte block, but &arr[0]
still has to point to the 0th byte of the block.
 
M

Michael Angelo Ravera

In "angels on the head of a pin mode", as there is nothing other than an
implementation defined way to convert a pointer to an integer:
a) it could /print/ 4b2, 4b1, 4b0 even if they were ascending up the
memory (I'm pretty sure of this one) - ie, %p could just subtract the
actual pointer address from all-1s.

Agreed -- except that %p converts a pointer to a string, not
(necessarily) to an integer.
b) (I'm slightly less sure).  If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.

I think pointers would have to keep track of the size of the blocks
they're pointing to.  For example, given char arr[100], &arr, in
your model, points to the end of the 100-byte block, but &arr[0]
still has to point to the 0th byte of the block.

I know of one implementation that ran character arrays from highest
memory down and binary arrays from lowest memory up on little endian
processors in order that processors of opposite byte sex could share
binary structures with each other.
 
K

Keith Thompson

Michael Angelo Ravera said:
b) (I'm slightly less sure).  If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.

I think pointers would have to keep track of the size of the blocks
they're pointing to.  For example, given char arr[100], &arr, in
your model, points to the end of the 100-byte block, but &arr[0]
still has to point to the 0th byte of the block.

I know of one implementation that ran character arrays from highest
memory down and binary arrays from lowest memory up on little endian
processors in order that processors of opposite byte sex could share
binary structures with each other.

One implementation of what? If you're referring to a C implementation,
what do you mean by "binary arrays"?
 
M

Michael Angelo Ravera

b) (I'm slightly less sure).  If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.
I think pointers would have to keep track of the size of the blocks
they're pointing to.  For example, given char arr[100], &arr, in
your model, points to the end of the 100-byte block, but &arr[0]
still has to point to the 0th byte of the block.
I know of one implementation that ran character arrays from highest
memory down and binary arrays from lowest memory up on little endian
processors in order that processors of opposite byte sex could share
binary structures with each other.

One implementation of what?  If you're referring to a C implementation,
what do you mean by "binary arrays"?

Mistyped "binary number", that is to say, integers. It was a whole OS
that was heavily into Bilaterally Defined Binary Data ("BDBD").
 
K

Keith Thompson

Michael Angelo Ravera said:
Michael Angelo Ravera said:
b) (I'm slightly less sure).  If all pointers were to the top ends of
blocks of memory, and +/- worked the wrong way round for pointers,
you'd never know.
I think pointers would have to keep track of the size of the blocks
they're pointing to.  For example, given char arr[100], &arr, in
your model, points to the end of the 100-byte block, but &arr[0]
still has to point to the 0th byte of the block.
I know of one implementation that ran character arrays from highest
memory down and binary arrays from lowest memory up on little endian
processors in order that processors of opposite byte sex could share
binary structures with each other.

One implementation of what?  If you're referring to a C implementation,
what do you mean by "binary arrays"?

Mistyped "binary number", that is to say, integers. It was a whole OS
that was heavily into Bilaterally Defined Binary Data ("BDBD").

My real question is whether it did this for C. Having arrays of char
and arrays of int, for example, run in opposite directions would
have some interesting implications for how C pointer arithmetic
would have to be implemented. For languages that don't tie array
indexing and pointer arithmetic the way C does, it wouldn't be as
much of an issue.
 

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,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top