Pointer conversions

C

CBFalconer

Ioannis said:
CBFalconer said:
Ioannis Vranos wrote:

Correction:

array_2d[0] is an array of 5 ints.
array2d[0] is an array of 5 ints and it "behaves" (I do not know
the accurate technical term)as a pointer to array_2d[0][0], that is
*(array_2d[0]) is array_2d[0][0].

No. Don't drop the details. *(array_2d[0]) is a pointer to an
array of 5 ints. array_2d[0][0] is an int. Just one.

Actually my correction with addition of parentheses was not needed.

Given: int array_2d[10][5];

array_2d behaves like a pointer to an array of 5 ints.
array2d_[0] behaves like a pointer to array_2d[0][0];

No it isn't. For example (remembering that array_2d[0][0] is an
int) try the following:

[1] c:\c\junk>cat junk.c
#include <stdio.h>

int testfunct(void) {
int array_2d[10][5] = {{0}};
int test;

printf("sizeof array_2d[0] is %d\n",
(int)(sizeof array_2d[0]));
test = array_2d[0];
return 1;
}

int main(void) {testfunct(); return 0;}

[1] c:\c\junk>cc junk.c
junk.c: In function `testfunct':
junk.c:9: warning: assignment makes integer from pointer without
a cast

[1] c:\c\junk>a
sizeof array_2d[0] is 20
 
K

Keith Thompson

CBFalconer said:
Ioannis Vranos wrote: [...]
array2d[0] is an array of 5 ints and it "behaves" (I do not know
the accurate technical term)as a pointer to array_2d[0][0], that
is *array_2d[0] is array_2d[0][0].

No it doesn't so "behave". It behaves as an array of 5 ints.
Under many circumstances it will be passed to other routines by a
pointer to its first element. This allows accessing the array
components, but does not limit the size (leading to overrun
errors).

Yes, but to be precise, passing it as a function argument is just one
of the many contexts in which an array expression is implicitly
converted to a pointer to the array's first element. This conversion
always happens *except* when the array expression is an argument to a
unary "&" or "sizeof" operator, or when it's a string literal used as
an initializer for an array.

Argument passing is perhaps the most common case where this conversion
happens (though array indexing might beat it), but there's nothing
special about it. The conversion happens when the expression is
evaluated, before it's even passed as an argument.

(Didn't we have this discussion just recently?)
 
I

Ioannis Vranos

CBFalconer said:
[1] c:\c\junk>a
sizeof array_2d[0] is 20

int array_2d[10][5];


I do not understand what you mean. array_2d[0] is an array of 5 ints and
it also behaves as a pointer to the first element of that array, that is
as a pointer to array[0][0].

That is, *array[0] is array[0][0].
 
C

CBFalconer

Keith said:
CBFalconer said:
Ioannis Vranos wrote: [...]
array2d[0] is an array of 5 ints and it "behaves" (I do not know
the accurate technical term)as a pointer to array_2d[0][0], that
is *array_2d[0] is array_2d[0][0].

No it doesn't so "behave". It behaves as an array of 5 ints.
Under many circumstances it will be passed to other routines by a
pointer to its first element. This allows accessing the array
components, but does not limit the size (leading to overrun
errors).

Yes, but to be precise, passing it as a function argument is just one
of the many contexts in which an array expression is implicitly
converted to a pointer to the array's first element. This conversion
always happens *except* when the array expression is an argument to a
unary "&" or "sizeof" operator, or when it's a string literal used as
an initializer for an array.

Argument passing is perhaps the most common case where this conversion
happens (though array indexing might beat it), but there's nothing
special about it. The conversion happens when the expression is
evaluated, before it's even passed as an argument.

(Didn't we have this discussion just recently?)

I wasn't trying for a discussion, just correcting Ioannis'
misconceptions about arrays.
 
B

Ben Bacarisse

CBFalconer said:
Ioannis said:
CBFalconer said:
Ioannis Vranos wrote:

Correction:

array_2d[0] is an array of 5 ints.
array2d[0] is an array of 5 ints and it "behaves" (I do not know
the accurate technical term)as a pointer to array_2d[0][0], that is
*(array_2d[0]) is array_2d[0][0].

No. Don't drop the details. *(array_2d[0]) is a pointer to an
array of 5 ints. array_2d[0][0] is an int. Just one.

Actually my correction with addition of parentheses was not needed.

Given: int array_2d[10][5];

array_2d behaves like a pointer to an array of 5 ints.
array2d_[0] behaves like a pointer to array_2d[0][0];

No it isn't. For example (remembering that array_2d[0][0] is an
int) try the following:

[1] c:\c\junk>cat junk.c
#include <stdio.h>

int testfunct(void) {
int array_2d[10][5] = {{0}};
int test;

printf("sizeof array_2d[0] is %d\n",
(int)(sizeof array_2d[0]));
test = array_2d[0];

The compiler diagnostic that you quote shows that array_2d[0] can not
be assigned to an int, but I can't see how that helps clarify things.
The output of the printf shows that array_2d[0] is not converted to
pointer when it is the operand of sizeof, but if that was your point
would it not have been simpler just to say so, or at least to
illustrate it with a correct program? The fact you post a diagnostic
suggests you think it illustrates something.

Ioannis: Your term "behaves" is not a bad one. You state you don't
know the correct terminology, but the trouble is there is no simple
way to say what you are trying to say. The standard puts it like
this:

Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type "array of type" is converted to an
expression with type "pointer to type" that points to the initial
element of the array object

but it is very tedious to keep saying that! The upshot is that one
can't always talk about the type of a part of expression in C. You
need to see the whole thing, or at least to keep saying "unless this
is the operand of...".
return 1;
}

int main(void) {testfunct(); return 0;}

[1] c:\c\junk>cc junk.c
junk.c: In function `testfunct':
junk.c:9: warning: assignment makes integer from pointer without
a cast
 
B

Barry Schwarz

CBFalconer said:
Ioannis Vranos wrote:

Correction:

array_2d[0] is an array of 5 ints.
array2d[0] is an array of 5 ints and it "behaves" (I do not know
the accurate technical term)as a pointer to array_2d[0][0], that is
*(array_2d[0]) is array_2d[0][0].

No. Don't drop the details. *(array_2d[0]) is a pointer to an
array of 5 ints. array_2d[0][0] is an int. Just one.


Actually my correction with addition of parentheses was not needed.

Given: int array_2d[10][5];

array_2d behaves like a pointer to an array of 5 ints.
array2d_[0] behaves like a pointer to array_2d[0][0];

Why the inconsistency in your description - one with a type and one
with an object?

The rule is very straight forward: "Except when it is the operand of
the sizeof operator or the unary & operator, or is a string literal
used to initialize an array, an expression that has type ‘‘array of
type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object..."

The expression
array_2d
is converted to a pointer to array_2d[0] which has type pointer to
array of 5 int and which is expressed syntactically as
&array_2d[0]
which has type
int (*)[5]

The expression
array_2d[0]
is converted to a pointer to array_2d[0][0] which has type pointer to
int and which is expressed syntactically as
&array_2d[0][0]
which has type
int *


Remove del for email
 
I

Ioannis Vranos

Barry said:

[Fixed the typos a bit]
>> Actually my correction with addition of parentheses was not needed.
>>
>> Given: int array[10][5];
>>
>> array behaves like a pointer to an array of 5 ints.
>> array[0] behaves like a pointer to array[0][0];
>
> Why the inconsistency in your description - one with a type and one
> with an object?
>
> The rule is very straight forward: "Except when it is the operand of
> the sizeof operator or the unary & operator, or is a string literal
> used to initialize an array, an expression that has type ‘‘array of
> type’’ is converted to an expression with type ‘‘pointer to type’’
> that points to the initial element of the array object..."
>
> The expression
> array
> is converted to a pointer to array[0] which has type pointer to
> array of 5 int and which is expressed syntactically as
> &array[0]
> which has type
> int (*)[5]
>
> The expression
> array[0]
> is converted to a pointer to array[0][0] which has type pointer to
> int and which is expressed syntactically as
> &array[0][0]
> which has type
> int *
>


Given the above you mentioned, and AFAIK, array[0] *is* an array of 5
ints, which also behaves like a pointer to an array of 5 ints.
 
I

Ioannis Vranos

Corrected:


Ioannis said:
[Fixed the typos a bit]
Actually my correction with addition of parentheses was not needed.

Given: int array[10][5];

array behaves like a pointer to an array of 5 ints.
array[0] behaves like a pointer to array[0][0];

Why the inconsistency in your description - one with a type and one
with an object?

The rule is very straight forward: "Except when it is the operand of
the sizeof operator or the unary & operator, or is a string literal
used to initialize an array, an expression that has type ‘‘array of
type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object..."

The expression
array
is converted to a pointer to array[0] which has type pointer to
array of 5 int and which is expressed syntactically as
&array[0]
which has type
int (*)[5]

The expression
array[0]
is converted to a pointer to array[0][0] which has type pointer to
int and which is expressed syntactically as
&array[0][0]
which has type
int *


Given the above you mentioned, and AFAIK, array is an array of [10][5]
elements which behaves like a pointer to its first element, that is like
a pointer to array[0], that is, like a pointer to an array of 5 elements.

array[0] is an array of 5 elements, which behaves like a pointer to its
first element, that is like an int *.


array[0] *is* an array of 5
ints, which also behaves like a pointer to the first element.
 
I

Ioannis Vranos

Corrected again (my last version):

Ioannis said:
Ioannis said:
[Fixed the typos a bit]
Actually my correction with addition of parentheses was not needed.

Given: int array[10][5];

array behaves like a pointer to an array of 5 ints.
array[0] behaves like a pointer to array[0][0];

Why the inconsistency in your description - one with a type and one
with an object?

The rule is very straight forward: "Except when it is the operand of
the sizeof operator or the unary & operator, or is a string literal
used to initialize an array, an expression that has type ‘‘array of
type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object..."

The expression
array
is converted to a pointer to array[0] which has type pointer to
array of 5 int and which is expressed syntactically as
&array[0]
which has type
int (*)[5]

The expression
array[0]
is converted to a pointer to array[0][0] which has type pointer to
int and which is expressed syntactically as
&array[0][0]
which has type
int *


Given the above you mentioned, and AFAIK, array is an array of [10][5]
elements which behaves like a pointer to its first element, that is like
a pointer to array[0], that is, like a pointer to an array of 5 elements.

array[0] is an array of 5 elements, which behaves like a pointer to its
first element, that is like an int *.
 
K

Keith Thompson

Ioannis Vranos said:
Barry Schwarz wrote:
[Fixed the typos a bit]
Actually my correction with addition of parentheses was not needed.

Given: int array[10][5];

array behaves like a pointer to an array of 5 ints.
array[0] behaves like a pointer to array[0][0];

Why the inconsistency in your description - one with a type and one
with an object?

The rule is very straight forward: "Except when it is the operand of
the sizeof operator or the unary & operator, or is a string literal
used to initialize an array, an expression that has type ‘‘array of
type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object..."
[...]

Given the above you mentioned, and AFAIK, array[0] *is* an array of 5
ints, which also behaves like a pointer to an array of 5 ints.

I think the phrase "behaves like" is causing problems.

I think that what's really causing problems (at least for me) is
a bit of ambiguity about the meaning of the name of something.

Let's take a simpler example, to avoid any confusion about
multidimensional arrays. Given:

int foo[20];

When I talk about ``foo'' in an English text discussion, am I
referring to the declared object whose name is ``foo'', or am I
talking about ``foo'' as a C expression?

The object whose name is ``foo'' is an array; it's not a pointer, and
it doesn't act like a pointer.

The C expression ``foo'', which is a primary expression (specifically
an identifier) *refers* to the object, but as an expression it can be
either of array type (if it's the operand of a unary "sizeof" or "&")
or be converted to pointer type (in any other context).

Going back to the original example, if we're talking about the
*object* array[0], it's an array object. It doesn't behave like a
pointer. In particular, it doesn't behave like a pointer object;
there is no pointer object here. But if we're talking about the
*expression" array[0], it's often implicitly converted to a pointer;
in that sense, you could say that it (sometimes!) "behaves like" a
pointer.
 

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,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top