This C program prints 1 - why?

R

radnus2004

main()
{
static int a[] = {1,2,3};
printf("&a[1]-&a[0]=%u\n",&a[1]-&a[0]);
}

If you compile the above program and run it prints 1.
Why?

I printed &a[0] and &a[1] separately and the difference
is 4 and not 1

Question: Huh?
Please see below:
&a[0]=133208 &a[1]=133212
&a[1]-&a[0] = 1
 
J

jdallen2000

If you compile the above program and run it prints 1.

&a[1] == (a+1)
&a[1] - &a[0] == (a+1) - a == 1
See the FAQ

Yes, you get a different difference if you coerce &a[x] to
integer, but note that floats would similarly have a different
difference. As explained in this newsgroup before, C wouldn't
be C if it did this different difference differently.

James
 
B

bluetent

When you use "&a[1]-&a[0]", the complier will count how many objects
between a[1] and a[0].
If you want to count how many bytes between them, you should use
"(int)&a[1]-(int)&a[0]".

(e-mail address removed)
 
R

Richard Bos

[ Get a real newsreader, or learn how to use Google properly. I've had
to manually reinstate the context here, because you removed it all. ]

(Implicit int has been removed in C99, btw. Better get used to
explicitly writing int main(void).)
{
static int a[] = {1,2,3};
printf("&a[1]-&a[0]=%u\n",&a[1]-&a[0]);
}

If you compile the above program and run it prints 1.
Why?

When you use "&a[1]-&a[0]", the complier will count how many objects
between a[1] and a[0].

True, but...
If you want to count how many bytes between them, you should use
"(int)&a[1]-(int)&a[0]".

....wrong.
First of all, conversion of pointers to integers is
implementation-defined; the two ints you get are perhaps quite probably
sizeof(int) apart, but this is by no means guaranteed.
Second, an int is not a very good type to use for this, both because it
may not be large enough to hold the result (which would invoke UB), and
because it is signed, possibly resulting in unexpected values in rare
cases. In C99, uintptr_t is the obvious type for this; in C89, I'd use
unsigned long, which is still not ideal, but the best C89 has.
Third, the right solution is to use the properties of char pointers,
i.c., that any pointer can be reliably converted to them because chars
have alignment requirements of 1, and that subtraction of two char
pointers must result in a difference in bytes, again, because
sizeof(char) is 1. So you'd use:

printf("&a[1]-&a[0]=%u\n", (char *)&a[1]-(char *)&a[0]);

Richard
 
E

Emmanuel Delahaye

bluetent wrote on 28/12/04 :
When you use "&a[1]-&a[0]", the complier will count how many objects
between a[1] and a[0].
If you want to count how many bytes between them, you should use
"(int)&a[1]-(int)&a[0]".

I would have said

"(char *)&a[1]-(char *)&a[0]".

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
K

Keith Thompson

Novitas said:

What's correct? Please provide enough context to allow your readers
to figure out what you're talking about without going back to the
previous message.

As it happens, the previous message was *not* correct.

] When you use "&a[1]-&a[0]", the complier will count how many objects
] between a[1] and a[0].
] If you want to count how many bytes between them, you should use
] "(int)&a[1]-(int)&a[0]".

Converting pointers to int doesn't necessarily give you anything
meaningful, and I've used systems where the above will not work.
You may also use (char *)&a[1] - (char *)&[0]

That's ok (except that "&[0]" should be "&a[0]").
 
L

Lawrence Kirby

....

Third, the right solution is to use the properties of char pointers,
i.c., that any pointer can be reliably converted to them because chars

any pointer that points to a valid object or else is a null pointer,
specifically not any pointer to function unless the value is a null
pointer.
have alignment requirements of 1, and that subtraction of two char
pointers must result in a difference in bytes, again, because
sizeof(char) is 1. So you'd use:

printf("&a[1]-&a[0]=%u\n", (char *)&a[1]-(char *)&a[0]);

You're passing a value of type ptrdiff_t (possibly promoted) but you told
printf() that you're passing an unsigned int which is a type it cannot be.
This is a case where a cast is appropriate

printf("&a[1]-&a[0]=%u\n", (unsigned)((char *)&a[1]-(char *)&a[0]));

It is reasonable to assume that in this case the result is represenatble
as an unsigned int, but you would have to consider other types for the
more general case.

Lawrence
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top