tags:

views:

46808

answers:

11
A: 
0x12345678 # Arbitrary
0x1234567C
0x0000032A # Arbitrary
0x0000032E

Assuming 32 bit integers and pointers. Watch me be incredibly wrong!

EDIT: (Spoilers)

Okay, so this is the result:

0x0022FF60
0x0022FF64
0x0022FF60
0x0022FF70

I was right with the first one, but the second one is a pointer to four integers, so incrementing it increments the pointer by four times the value, in this case, 16 bytes, right?

Bernard
You are wrong! You are now allowed to run the program and see what happens (you still have to explain it.)
Edward Z. Yang
Well, not have to; just should. :-)
Edward Z. Yang
Charlie
+14  A: 
0x12345678
0x1234567C
0x12345678
0x12345688
wnoise
Pointer to int vs pointer to array of 4 integers.
wnoise
Excellent question, excellent answer. So cool, I still don't get it, so now I'm going back to my cave and think about it for a bit. +1 insightful to wnoise :)
Tom
A: 

Isn't the answer dependent on the direction of stack growth, this hasn't been specified?

No, because increasing array indexes refer to increasing addresses, no matter which way the stack grows.
Greg Hewgill
No - as Greg said...
Jonathan Leffler
A: 

Assume that sp is 0x000010000

sizeof(int) is 4

sizeof(int *) is 8

Output will be:

0x000010000
0x000010004
0x000010000
0x000010008

& operator applied to an array does nothing, it's a no-op, since the array is already a pointer.

Moishe
An array is not a pointer. However, when you reference the array as shown, it becomes a pointer.
Jonathan Leffler
Also, as the other answers show, the fourth value is 16 bytes 0x10 more than the first.
Jonathan Leffler
Moishe
A: 

Is the last one supposed to be address of array + 1 byte?

  • 0x12345678
  • 0x1234567C
  • 0x12345678
  • 0x12345679

UPDATE

Based on Bernard's advice, it would then be address + extra 4 bytes address

  • 0x12345678
  • 0x1234567C
  • 0x12345678
  • 0x1234567C

Which is supposed to be wrong answer. I guess not touching C for nearly 15 yrs has its disadvantages :-p

UPDATE2

End lesson is address + extra 16 bytes (according to size of array 4 ints)

  • 0x12345678
  • 0x1234567C
  • 0x12345678
  • 0x12345688
icelava
Pointer arithmetic doesn't work like straight arithmetic. Any addition is converted into the pointer size first.
Bernard
Pointer size, so that would be 32bit address = 4 bytes.
icelava
Jonathan Leffler
I did consider that, but was not able to verify whether the compiler would indeed take into consideration the array size or not. Is there some documentationo that explains this?
icelava
"Any addition is converted into the pointer size first" -- I know you meant "size of the pointed-to object" but some of the other posters here don't know you meant that. "Is there some documentationo" -- C language definition 38 years ago, maybe some textbooks since then too.
Windows programmer
Richard T
Heh i was asking for some Internet material that discusses this, all that I came across only mentioned addressing between elements in an array, not the whole array itself. But at this stage it is pretty much confirmed an array's size is statically tied to its pointer arithmetic. Thanks.
icelava
Yes, I did mean size of pointed to object. Sorry for the confusion. :(
Bernard
+2  A: 

wow... it's been a loooong time since the good ol days ...

but... still.

x and &x are basically the same thing here are they not, arrays in C are just syntactic sugar over pointer arithmetic, so my guess would be that basically twice the same pair of lines to be the output of the program above... unless the adress of an adress yields yet another address...

ho... the pain.. my brain hurts... need more beer


weeeel will you look at that, they are both addresses but the pointer arithmetic will be affected differently by the & operator... typing the pointer differently

x being the address of the first element (typed int)
&x being the address of the array of int (typed int[4])

nice, thanks

Newtopian
Yeah, if I saw that second piece of work in real code, I would be quite confused. But it does work differently, at least on this machine, so I suppose I should do a little boning up on the stuff.
Bernard
Brian R. Bondy
I wonder who upvoted this answer.
Windows programmer
somebody who already had more beer ;-D
icelava
darn you people are fast... yes Brian, I was editing while you answered ;-).
Newtopian
+58  A: 

The output is undefined behavior because %p requires that the pointer be cast to void * since other pointer types might not have the same size and representation as void *. Assuming that part of the program is corrected, the output would be implementation defined. The output would be an implementation defined representation of the following values, assuming n = the pointer value of the address of the first element of the array:

n
n + sizeof(int)
n 
n + 4 * sizeof(int)

The reason for the first 3 lines should be obvious. The reason for the last line is because &x is of type int(*)[4] and not int *.

Chris Young
I noticed the %p and said to myself, "Gee, I don't remember using _that_ one in, oh... -damn- too many years to remember!"
Richard T
it's not much use except for a poor man's debugging. One other rather esoteric use is to printf %p out pointer values to a file then scanf them back with %p. The standard guarantees the resulting pointer be equal to the one written out if it's the same program.
Chris Young
The part on undefined behavior is wrong. All pointers except function pointers and pointers to member functions can be casted to/from `void *` according to the standard. Things such as DOS far pointers may be exceptions, but they're not included in the standard.Everything else is correct, though.
Paolo Bonzini
@Paolo: Certainly the can be cast to and from `void *`, but where are they? `printf()` is a variadic function, meaning that pointer arguments are passed as is, and are not cast. Therefore, passing in an `int *` and using it as a `void *` means that an uncast `int *` is used as a `void *`, which is not guaranteed to work. A function explicitly taking a `void *` could take any data pointer, but that's not what `printf` does.
David Thornley
@David: You're right: "If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases: [...] one type is pointer to void and the other is a pointer to a character type." I wonder if there is an actual machine that prompted the committee to make the rule this strict, because I have a hard time imagining a `void *` incompatible with another (non-function) pointer.
Paolo Bonzini
@Paolo: There have been some weird machines. The CDC 6600 had 60-bit words, so it would have had to have 10-bit `char` if there was a C compiler for it, and the `char *` and hence the `void *` would have needed an offset in the word. That's the only computer I personally have ever worked on enough to know addressing where you couldn't designate a byte address with one binary number (although the machine language didn't necessarily use that number, the IBM 360 having sixteen-bit pointers, first four for register used as base, next twelve for offset).
David Thornley
+105  A: 
Edward Z. Yang
Wow, very interesting. I've been using pointers for years and never knew the difference between a pointer to an array and a pointer to the first element of the array.Thanks for posting this question (and answer)! You learn something new everyday. :)
Bob Somers
Question about #4, assuming an int is 32 bits (4 bytes), why is the address 10 more and not 16?Oooooohhh, writing it out made me realize I'd forgotten it was Hex... ha!
swilliams
Upvoting you if only for using readable addresses. I wonder why everyone went for 0x12345678 as opposed to, say, 0. Or 5. (OK, they're unlikely, but still?)
aib
A: 

Like said Bernard the first time:

0x12345678 # Arbitrary

0x1234567C

0x0000032A # Arbitrary

0x0000032E

&x's type is int**, which size is 4 in 32bit... so &x + 1 = 0x0000032E

Nicolas Dorier
Look more carefully at the other answers, and try compiling/running the program yourself.
Edward Z. Yang
+2  A: 

Technically, there are two "correct" answers because even on a 32-bit architecture, int is allowed to be 16-bit.

zvrba
Actually, sizeof(int)==1 is also legitimate, if characters are 16-bits (as with some DSP's).
supercat
A: 

Without compiling the program, what does it output, and why? If you think that a certain output will be arbitrary, say so, invent a value, and then pretend that was the value that was output.

Program wont compile. :)

brooksbp