Pointers in C

C

Clark S. Cox III

rafalp said:
I'm not making anywhere the assumption that they are adjacent. My point
was to explain to the OP that for two given objects o1, o2 of the same type

&o1 - &o2 := (addressof(o1) - addressof(o2)) / sizeof(objects)

That's all.

Even that isn't guaranteed.

(&o1 - &o2) could be (42) and ((char*)&o1 - (char*)&o2) could be
('bananas'). Subtracting pointers to two objects that aren't part of
some other object (i.e. array, structure, union, etc.) is undefined.
 
S

santosh

rafalp said:
santosh wrote:


I'm not making anywhere the assumption that they are adjacent. My point
was to explain to the OP that for two given objects o1, o2 of the same type

&o1 - &o2 := (addressof(o1) - addressof(o2)) / sizeof(objects)

That's all.

That holds true only for two given objects o1, o2 of the same type
*and part of an array*. Two arbitrary objects can be placed anywhere
in memory and hence the difference of their addresses , (which invokes
undefined behaviour), need not be any expected value at all. The two
objects in OP's post were two arbitrary objects, hence his expectation
of any sensible output as well as your explanation based on an
assumption that the OP may not know about, are both wrong.
 
R

rafalp

santosh said:
That holds true only for two given objects o1, o2 of the same type
*and part of an array*. Two arbitrary objects can be placed anywhere
in memory and hence the difference of their addresses , (which invokes
undefined behaviour), need not be any expected value at all. The two
objects in OP's post were two arbitrary objects, hence his expectation
of any sensible output as well as your explanation based on an
assumption that the OP may not know about, are both wrong.

OK. That's what C standard says.
I'm pretty sure that compilers perform the same operations when
subtracting any two pointers, no matter if they are related or not.
But still subtracting unrelated pointers is of little sense to me.
 
R

rafalp

Clark said:
Even that isn't guaranteed.

(&o1 - &o2) could be (42) and ((char*)&o1 - (char*)&o2) could be
('bananas'). Subtracting pointers to two objects that aren't part of
some other object (i.e. array, structure, union, etc.) is undefined.

I don't understand what you mean. (&o1 - &o2) and ((char*)&o1 -
(char*)&o2) give different results even if o1 and o2 are the part of the
same array unless sizeof(o1) == sizeof(char).
 
C

Clark S. Cox III

rafalp said:
OK. That's what C standard says.
I'm pretty sure that compilers perform the same operations when
subtracting any two pointers, no matter if they are related or not.

*Your* compiler might do that but not every compiler does that. Think of
a segmented architecture with completely separate memory spaces.
But still subtracting unrelated pointers is of little sense to me.

Of course it makes little sense--the result is completely undefined.
 
C

Clark S. Cox III

rafalp said:
I don't understand what you mean. (&o1 - &o2) and ((char*)&o1 -
(char*)&o2) give different results even if o1 and o2 are the part of the
same array unless sizeof(o1) == sizeof(char).

If they are *not* part of the same array, there are no restrictions on
what either subtraction could yield, nor is there any guarantee that the
two results are related in any way (hence the "42" and "'bananas'").
 
R

rafalp

Clark S. Cox III napisał(a):
*Your* compiler might do that but not every compiler does that. Think of
a segmented architecture with completely separate memory spaces.

Can you think of a real that checks relate-ness of pointers prior to
subtracting them and performs two different algorithms depending on
whether they are related or not?
 
S

santosh

rafalp said:
Clark S. Cox III napisał(a):

Can you think of a real that checks relate-ness of pointers prior to
subtracting them and performs two different algorithms depending on
whether they are related or not?

No. Pointer arithmetic is valid only for pointers to the same object
or objects within an array. For other cases, the behaviour is
undefined. Specific implementations will usually emit a diagnostic but
go ahead and perform the operation anyway. Whether the result makes
sense is upto the programmer. In flat memory models and for objects of
the same type and scope, it *might* make sense. Most programs don't
need such information anyway.
 
R

Richard Bos

rafalp said:
Clark S. Cox III napisał(a):

Can you think of a real that checks relate-ness of pointers prior to
subtracting them and performs two different algorithms depending on
whether they are related or not?

Who's talking about two different _algorithms_? For some computers
(e.g., under MS-DOS), subtracting a pointer in one segment from one in
another might use the same algorithm as subtracting two pointers from
the same segment, but exactly _because_ of this give "wrong", semi-
random results. For other computers, comparing a pointer in one ring to
a pointer in another ring might cause a security violation error at the
hardware level (i.e., before the C implementation can even react to it),
terminating the program with extreme prejudice.

Richard
 
R

rafalp

Richard said:
Who's talking about two different _algorithms_?

Actually santosh is. He said "not every compiler does that" in response
to my "compilers perform the same operations". That's why I asked.
For some computers
(e.g., under MS-DOS), subtracting a pointer in one segment from one in
another might use the same algorithm as subtracting two pointers from
the same segment, but exactly _because_ of this give "wrong", semi-
random results.

With that I fully agree. I have *not* stated anywhere in the discussion
that subtracting unrelated pointer makes any sense nor I'm defending
that thesis.
For other computers, comparing a pointer in one ring to
a pointer in another ring might cause a security violation error at the
hardware level (i.e., before the C implementation can even react to it),
terminating the program with extreme prejudice.

No, because you're not accessing memory in "another ring". Comparing
pointers is not the same as accessing memory they point to.
 
R

Richard Tobin

No, because you're not accessing memory in "another ring". Comparing
pointers is not the same as accessing memory they point to.

It might be that merely comparing or subtracting two addresses in
different rings causes an exception, because there may be no ordering
defined between addresses in different rings. (By the way, C requires
comparing for equality to work.)

-- Richard
 
K

Keith Thompson

rafalp said:
Richard Bos wrote: [...]
For other computers, comparing a pointer in one ring to
a pointer in another ring might cause a security violation error at the
hardware level (i.e., before the C implementation can even react to it),
terminating the program with extreme prejudice.

No, because you're not accessing memory in "another ring". Comparing
pointers is not the same as accessing memory they point to.

Comparing (using the relational operators <, <=, >, or >=) two
pointers that don't point to the same object invokes undefined
behavior. It's easy to assume that this will always yield some
sensible result, but the standard simply doesn't guarantee it.

If the standard required a flat linear address space, then the
relational operators could be required to yield consistent results;
for any two pointer of the same type, it could guarantee that exactly
one of x < y, x == y, x > y is true, and define a total ordering. But
that would make it more difficult to implement C on hardware with more
exotic memory models. The current definition makes it possible to
implement C on hardware on which pointer comparisons don't necessarily
yield consistent results, or even where attempting such a comparison
might crash the program.
 
O

Old Wolf

int main(void)
{
int x, y ;
int *p1 = &x;
int *p2 = &y;
printf("%d\n", (int)(p1-p2));
return 0;}

So we have the program (with the undefined behaviour fixed)

For some definitions of 'fixed' !
 
O

Old Wolf

santosh said:



Since unsigned char may not contain padding bits (see 6.2.6.2), the
answer is no.

You could have CHAR_BIT be 12, and signed char have 8 value
bits and 4 padding bits (for example).
 
M

Malcolm McLean

Richard Heathfield said:
CBFalconer said:


It is required to behave "as if" each byte has CHAR_BIT bits.


In which case it's "as if" they don't exist. So my answer stands.
The Nintendo 64 was one such computer.
There was a ninth bit which, if completely crazed, you could raid with
special assembly instructions
to squeeze some extra memory out of the system.
 
C

CBFalconer

rafalp said:
.... snip ...

Can you think of a real that checks relate-ness of pointers prior to
subtracting them and performs two different algorithms depending on
whether they are related or not?

It doesn't need to. The operation is undefined.
 
F

Flash Gordon

Old Wolf wrote, On 22/02/07 21:28:
For some definitions of 'fixed' !

Quite right, lets say the undefined behaviour other than the specific
piece that the OP was interested in. I agree the pointer subtraction
still invoked undefined behaviour and I should have mentioned that.
 
R

Richard Bos

rafalp said:
Actually santosh is. He said "not every compiler does that" in response
to my "compilers perform the same operations".

That doesn't mean that they don't follow the same algorithm. Even if
your compiled program follows the same algorithm, your OS or even your
memory controller could ensure that the result is different.
No, because you're not accessing memory in "another ring".

Accessing memory is irrelevant. Just comparing two pointers to different
security rings using < or > could cause a trap. And the Standard allows
it to.

Richard
 
D

Daniel Rudy

At about the time of 2/21/2007 11:43 AM, Richard Tobin stated the following:
The assumptions you listed are not sufficient to guarantee that the
objects are adjacent. It's likely that they are, but even then
there's no reason to assume that the result of the pointer subtraction
will be positive rather than negative.

We know from the original post that the result is 1 without the casts
to char *. So unless sizeof(char *) is negative (an interesting idea)
the difference after casting will also be positive.

-- Richard[/QUOTE]

Not necessarily. Did you see Flash Gordon's post (Message ID:
<[email protected]>) when he ran it on a AIX 5.3
machine? It gave -1 as the answer. Two different platforms gives two
different answers, both compiled with gcc.

As most of us here know, undefined behavior is undefined behavior:
anything can happen, any result is possible. It all depends on your
implementation, compiler, and platform.


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 
D

Daniel Rudy

At about the time of 2/20/2007 10:11 PM, Praveen stated the following:
Hi,

I came across a program as follows
main()
{
int x, y ;
int *p1 = &x;
int *p2 = &y;
printf("%d\n", p1-p2);
}

The output of the above program is 1.
Can some one explain me how it is 1.
Thanks in advance.

It's undefined behavior for reasons that others have pointed out.

In this case, x and y are placed ajacent in memory, so the difference is
1 since you are subtracting int pointers. Some people here have had -1
on their systems.

strata:/home/dr2867/c/test 1062 $$$ ->cat ub001.c


#include <stdio.h>

int main(void)
{
int x;
int y;
int *p1 = &x;
int *p2 = &y;
printf("%d\n", p1 - p2);
printf("p1 = %0#x\np2 = %0#x\n", (unsigned int)p1, (unsigned int)p2);

return(0);
}

strata:/home/dr2867/c/test 1063 $$$ ->./compile ub001 ub001.c

Output File: ub001

Input Files:
ub001.c

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wnested-externs -Wwrite-strings -Wflo
at-equal -Winline -Wtrigraphs -ansi -std=c89 -pedantic -ggdb3 -o ub001
ub001.c

strata:/home/dr2867/c/test 1064 $$$ ->./ub001
1
p1 = 0xbfbfec34
p2 = 0xbfbfec30
strata:/home/dr2867/c/test 1065 $$$ ->


Look at the values of p1 and p2. They are 4 off, but it returns 1
because sizeof(int) is 4...at least on my system and apparently yours too.




--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 

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,794
Messages
2,569,641
Members
45,354
Latest member
OrenKrause

Latest Threads

Top