int a[5] .. difference between a and &a

O

onkar

#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0


this means that a and its address is same ?? Please explain ..
 
R

Richard Heathfield

onkar said:
#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0

Invoking undefined behaviour can give any result whatsoever.
 
P

P.J. Plauger

onkar said:
#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0

Invoking undefined behaviour can give any result whatsoever.

Seems to me that a decays to an int * while &a is int[5] *.
Both are well formed and happen to have the same address value,
just different types. The only thing undefined about this
program is that %p strictly speaking accepts just a void *,
which *might* have a different representation than int * or
int[5] *. Add the casts and I'll bet you get the same printout,
in a well formed program.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
R

Richard Heathfield

P.J. Plauger said:
onkar said:
#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0

Invoking undefined behaviour can give any result whatsoever.

Seems to me that a decays to an int * while &a is int[5] *.

Well, int (*)[5], but yes. Neither is of type void *, however.
Both are well formed and happen to have the same address value,
just different types. The only thing undefined about this
program is that %p strictly speaking accepts just a void *,
which *might* have a different representation than int * or
int[5] *. Add the casts and I'll bet you get the same printout,
in a well formed program.

And what lesson will the OP draw from your apparent condoning of the cast
omission, I wonder?
 
S

Sourcerer

onkar said:
#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0


this means that a and its address is same ?? Please explain ..


No.
a is a pointer to an address where the array a[] begins. a[x] is thus an element
of that field, and the address of that element is calculated like this:

address = a + x * sizeof(int); //int is interchangeable here, depends on what
type of array you are using

&a doesn't mean anything. Since a is a pointer itself, there is no pointer to
that pointer (unless you explicitly declared there to be one). Pointer addresses
are remembered internally by the compiler and when the compiled program loads
into memory, they can be located on predefined places, depending on which part
of memory was the program loaded to. You have no access to these, and you don't
even need them. Most often, however, their relative position in the memory is
encoded into the very (binary) code of the program, so it's near to impossible
to extract them.

&a is therefore, not defined and it can be anything.

--
"It is easy in the world to live after the world's oppinion; it easy in solitude
to live after our own; but the great man is he who in the midst of the crowd
keeps with perfect sweetness the independence of solitude."
Ralph Waldo Emerson, Self-reliance 1841
http://pinpoint.wordpress.com/
 
S

Sourcerer

Sourcerer said:
address = a + x * sizeof(int); //int is interchangeable here, depends on what
type of array you are using

Just remembered, C language "knows" the size of an array element, so the address
is calculated thus:

address = a + x;

This will move the pointer 'address' to the x-th element in any type of array
'a', thanks to the programmers of the compiler who have made our lives easier in
this aspect of C.

--
"It is easy in the world to live after the world's oppinion; it easy in solitude
to live after our own; but the great man is he who in the midst of the crowd
keeps with perfect sweetness the independence of solitude."
Ralph Waldo Emerson, Self-reliance 1841
http://pinpoint.wordpress.com/
 
R

Richard Heathfield

Sourcerer said:
onkar said:
#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0


this means that a and its address is same ?? Please explain ..


No.
a is a pointer to an address where the array a[] begins.

Strictly, it is an array that, when evaluated, yields as its value the
address of its first element.

&a doesn't mean anything. Since a is a pointer itself,

But it isn't a pointer - it's an array name. When used as an operand to &
(or to sizeof) it is not evaluated, and thus does not decay into a pointer
value.

&a means "the address of the array of 5 ints named a".

<incorrect deductions snipped>
 
S

Sourcerer

Richard Heathfield said:
Sourcerer said:
No.
a is a pointer to an address where the array a[] begins.

Strictly, it is an array that, when evaluated, yields as its value the
address of its first element.

OK, that means that evaluated a = &a. &a is then the address of the array which
I earlier considered 'a' to be.
Only I have not been consistent in another matter earlier. &a isn't a pointer
(see example below). It is the value directly encoded into the binary processor
commands.
But it isn't a pointer - it's an array name. When used as an operand to &
(or to sizeof) it is not evaluated, and thus does not decay into a pointer
value.

<snip>

&a means "the address of the array of 5 ints named a".

Hmm... interesting how this subtlety affects program execution. Consider the
following program:
#include <stdio.h>
int main(void){
int a[5];
printf("%d, %d\n", sizeof(a), sizeof(&a));
return 0;
}

I first assumed this should give the output (if sizeof(int) = 4):
20, 4

This would be true if &a was a pointer, but it isn't. Execution of this program
gives the output:
20, 20

Why is the second value 20 as well? What exactly is
sizeof(&anything_that_is_not_a_pointer)?

--
"It is easy in the world to live after the world's oppinion; it easy in solitude
to live after our own; but the great man is he who in the midst of the crowd
keeps with perfect sweetness the independence of solitude."
Ralph Waldo Emerson, Self-reliance 1841
http://pinpoint.wordpress.com/
 
P

P.J. Plauger

P.J. Plauger said:
onkar said:

#include<stdio.h>
int main(int argc,char **argv){
int a[5]={1,2,3,4,5};
printf("%p\n%p\n",a,&a);
return 0;
}


gives me :
0xbfe837a0
0xbfe837a0

Invoking undefined behaviour can give any result whatsoever.

Seems to me that a decays to an int * while &a is int[5] *.

Well, int (*)[5], but yes. Neither is of type void *, however.
Both are well formed and happen to have the same address value,
just different types. The only thing undefined about this
program is that %p strictly speaking accepts just a void *,
which *might* have a different representation than int * or
int[5] *. Add the casts and I'll bet you get the same printout,
in a well formed program.

And what lesson will the OP draw from your apparent condoning of the cast
omission, I wonder?

That your quibble is off the point and about as useful as saying that
void main can set your house on fire. The interesting point here was
that two address calculations can yield the same value. That's what
the OP needed education about.

The more subtle point was that &a is well formed, despite widespread
confusion on the topic. (Witness the erroneous remarks by Sourceror.)
It took me three meetings of X3J11 to convince the committee that &a
should be well formed, despite the distracting misbehavior of Steve
Johnson's Portable C Compiler (which decayed arrays to pointers a bit
too eagerly).

And the pragmatic point is that the (void *) cast is indeed often
gratuitous in real-world code. Indeed, a couple of the more delicate
backward-compatibility features in Standard C depend on this common
pun. So telling a novice that two pointer values are equal only because
his program can give "any result whatever" is prissy and self serving.
It is certainly not edifying.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
P

P.J. Plauger

Richard Heathfield said:
Sourcerer said:
No.
a is a pointer to an address where the array a[] begins.

Strictly, it is an array that, when evaluated, yields as its value the
address of its first element.

OK, that means that evaluated a = &a.

I assume you mean a == &a, which is still ill formed. You're comparing
two different types of pointers. If you mean they have the same
address values, then I agree.
&a is then the address of the array which I
earlier considered 'a' to be.

No, a is the *name* of an array of 5 int. &a is a *pointer* to that
array.
Only I have not been consistent in another matter earlier. &a isn't a
pointer (see example below).

Actually it is (see challenge below).
It is the value directly encoded into the binary
processor commands.

It's "directly encoded" only in the sense that any known address
or constant is encoded. Otherwise, there's nothing magic about
the name of an array.

But it isn't a pointer - it's an array name. When used as an operand to &
(or to sizeof) it is not evaluated, and thus does not decay into a
pointer
value.

<snip>

&a means "the address of the array of 5 ints named a".
Correct.

Hmm... interesting how this subtlety affects program execution. Consider
the following program:
#include <stdio.h>
int main(void){
int a[5];
printf("%d, %d\n", sizeof(a), sizeof(&a));
return 0;
}

I first assumed this should give the output (if sizeof(int) = 4):
20, 4

This would be true if &a was a pointer, but it isn't. Execution of this
program gives the output:
20, 20

Why is the second value 20 as well? What exactly is
sizeof(&anything_that_is_not_a_pointer)?

I just tried this on EDG, GCC, and VC++. Only the last of the three
yields "20, 20", which is *incorrect*. The first two give "20, 4"
as they should. It's hard to understand subtleties like this when
leading compilers get them wrong.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

Sourcerer

P.J. Plauger said:
I assume you mean a == &a,

No. That wasn't programming but rather something of a pseudocode and the word
'evaluated' was part of it.
(evaluated a) = &a.
If you mean they have the same
address values, then I agree.

That is what I meant.
No, a is the *name* of an array of 5 int. &a is a *pointer* to that
array.

LOL, so I was correct at first about &a, then that test on VC++ got me
completely befuddled.


I didn't say that. :)
Hmm... interesting how this subtlety affects program execution. Consider the
following program:
#include <stdio.h>
int main(void){
int a[5];
printf("%d, %d\n", sizeof(a), sizeof(&a));
return 0;
}

I first assumed this should give the output (if sizeof(int) = 4):
20, 4

This would be true if &a was a pointer, but it isn't. Execution of this
program gives the output:
20, 20

Why is the second value 20 as well? What exactly is
sizeof(&anything_that_is_not_a_pointer)?

I just tried this on EDG, GCC, and VC++. Only the last of the three
yields "20, 20", which is *incorrect*. The first two give "20, 4"
as they should. It's hard to understand subtleties like this when
leading compilers get them wrong.

Grr. I'm switching to Linux... I have gcc there.

--
"It is easy in the world to live after the world's oppinion; it easy in solitude
to live after our own; but the great man is he who in the midst of the crowd
keeps with perfect sweetness the independence of solitude."
Ralph Waldo Emerson, Self-reliance 1841
http://pinpoint.wordpress.com/
 
S

Sourcerer

P.J. Plauger said:
No, a is the *name* of an array of 5 int. &a is a *pointer* to that
array.

That is what I said here, if you disregard the confusion with my compiler. I
earlier considered 'a' to be a pointer to the array. And since &a is the
pointer, then it's value is the address.

--
"It is easy in the world to live after the world's oppinion; it easy in solitude
to live after our own; but the great man is he who in the midst of the crowd
keeps with perfect sweetness the independence of solitude."
Ralph Waldo Emerson, Self-reliance 1841
http://pinpoint.wordpress.com/
 
C

Chris Torek

The more subtle point was that &a is well formed, despite widespread
confusion on the topic. (Witness the erroneous remarks by Sourceror.)
It took me three meetings of X3J11 to convince the committee that &a
should be well formed, despite the distracting misbehavior of Steve
Johnson's Portable C Compiler (which decayed arrays to pointers a bit
too eagerly).

I added "&arr" support to that particular compiler.

All that was required was *removing* two or three lines (in the .y
file containing the grammar) that produced a warning and substituted
a different type/value pair. Everything else already worked fine.
(I was a bit surprised.)
 
B

Ben Bacarisse

While discussing the difference between a and &a when a is an array
Sourcerer said:
Richard Heathfield said:
Sourcerer said:
No.
a is a pointer to an address where the array a[] begins.

Strictly, it is an array that, when evaluated, yields as its value the
address of its first element.

OK, that means that evaluated a = &a. &a is then the address of the
array which I earlier considered 'a' to be.
Only I have not been consistent in another matter earlier. &a isn't a
pointer (see example below). It is the value directly encoded into the
binary processor commands.
But it isn't a pointer - it's an array name. When used as an operand to &
(or to sizeof) it is not evaluated, and thus does not decay into a pointer
value.

<snip>

&a means "the address of the array of 5 ints named a".

Hmm... interesting how this subtlety affects program
execution.

Another way to see the difference is like this:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int a[5];
printf("&a+1=%p, a+1=%p\n", (void *)(&a + 1), (void *)(a + 1));
return EXIT_SUCCESS;
}
 
B

Barry Schwarz

Richard Heathfield said:
Sourcerer said:
No.
a is a pointer to an address where the array a[] begins.

Strictly, it is an array that, when evaluated, yields as its value the
address of its first element.

OK, that means that evaluated a = &a. &a is then the address of the array which

The do point to the same address. However, since they are of
different and incompatible types, equality has little meaning.
Furthermore, assigning each expression to a pointer of the appropriate
type could result in different bit patterns. The standard does not
require the two pointers to use the same representation or to even be
of the same size.
I earlier considered 'a' to be.
Only I have not been consistent in another matter earlier. &a isn't a pointer
(see example below). It is the value directly encoded into the binary processor
commands.

&a isn't a pointer simply because it is not an object. It is an
expression which can be evaluated. The expression does have **type**
pointer to array N of int.

snip
Hmm... interesting how this subtlety affects program execution. Consider the
following program:
#include <stdio.h>
int main(void){
int a[5];
printf("%d, %d\n", sizeof(a), sizeof(&a));

sizeof returns a size_t which need not be a flavor of int. If you
want to use %d, cast the result.
return 0;
}

I first assumed this should give the output (if sizeof(int) = 4):
20, 4

If sizeof(int) is 4, the 20 is reasonable. Why do you think the
sizeof(int(*)[5]) should be 4? The two are not related.
This would be true if &a was a pointer, but it isn't. Execution of this program
gives the output:
20, 20

This only proves your compiler is broken or maybe sizeof(int(*)[5]) is
actually 20. I'm using VC 6 and, after adding the casts, mine
produces the same erroneous result. However, adding
int (*b)[5];
b = &a;
printf("%d, %d\n", (int)sizeof(a), (int)sizeof(b));
before the first printf produces the expected result of 20, 4.

Since we know a is not evaluated when the operand of the & operator,
the sizeof(&a) and the sizeof(b) must be the same.
Why is the second value 20 as well? What exactly is
sizeof(&anything_that_is_not_a_pointer)?

For any type T and an object t of that type, sizeof(&t) must be the
same as sizeof(T*).


Remove del for email
 
K

Keith Thompson

Barry Schwarz said:
[...]
I earlier considered 'a' to be. Only I have not been consistent in
another matter earlier. &a isn't a pointer (see example below). It
is the value directly encoded into the binary processor commands.

&a isn't a pointer simply because it is not an object. It is an
expression which can be evaluated. The expression does have **type**
pointer to array N of int.
[...]

That's a matter of some controversy. One point of view is that the
unadorned term "pointer" should refer only to *objects* of pointer
type; values of pointer type should be called "addresses", or perhaps
"pointer values".

That's my own preference as well, but the standard does not
consistently use the terms that way. See, for example, the description
of the value returned by malloc():

The malloc function returns either a null pointer or a pointer to
the allocated space.

I think we have to accept that the word "pointer" can refer to a
pointer value, and that &a is therefore a pointer, at least as the
standard uses the term.
 
R

Richard Heathfield

P.J. Plauger said:
That your quibble is off the point and about as useful as saying that
void main can set your house on fire.

Since it can, I'd have thought that to be a rather important thing to say.
Undefined behaviour *can* cause real effects in the real world, and I've
seen machines trashed by it. I suppose you have, too. And that's why it's
neither a quibble nor off the point to indicate to the OP that his
program's results are untrustworthy and that his first act should be to
correct his program.
The interesting point here was
that two address calculations can yield the same value. That's what
the OP needed education about.

That is *one* of the things the OP needed education about, yes.

<snip>
 

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,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top