Array delarator an lvalue? 
Author Message
 Array delarator an lvalue?

Someone pointed out to me recently that given:

char x[10];

&x == x is true.

I would have thought that &x isn't even legal.  K&R A7.4.2 states that
the operand for the "&" operator must be an lvalue or a function.  GCC
2.95.3, at least, like it.

Greg



Sat, 22 May 2004 01:46:53 GMT  
 Array delarator an lvalue?

Quote:
> Someone pointed out to me recently that given:
> char x[10];
> &x == x is true.
> I would have thought that &x isn't even legal.  K&R A7.4.2 states that
> the operand for the "&" operator must be an lvalue or a function.  GCC
> 2.95.3, at least, like it.

The array IS an lvalue. It just isn't a modifiable one.

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"Keep shooting, sooner or later you're bound to hit something."
   - Misfire



Sat, 22 May 2004 01:50:21 GMT  
 Array delarator an lvalue?

Quote:

>  Someone pointed out to me recently that given:

>  char x[10];

>  &x == x is true.

That somebody was mistaken. The pointers on either side of the ==
operator have different types (with no implicit conversion between
these types), so this comparison violates a constraint.
However, either of
    (char *) &x == x
or
    &x == (char (*)[10]) x
should evaluate to 1, I believe.

Quote:
>  I would have thought that &x isn't even legal.  K&R A7.4.2 states that
>  the operand for the "&" operator must be an lvalue or a function.  GCC
>  2.95.3, at least, like it.

The operand of the & operator *is* an lvalue, above. According to
what Chris Torek likes to call The Rule, arrays are converted to
pointers which are not lvalues *except* when they are the operand of
sizeof or the address-of (unary &) operator.
Thus, in &x, x is still an array and an lvalue, and &x is a pointer
to this whole array. &x therefore has type pointer to array 10 of
char, or `char (*)[10]'.

Gergo

--
A beginning is the time for taking the most delicate care that balances are
correct.
                -- Princess Irulan, "Manual of Maud'Dib"



Sat, 22 May 2004 01:58:53 GMT  
 Array delarator an lvalue?

Quote:

> Someone pointed out to me recently that given:

> char x[10];

> &x == x is true.

> I would have thought that &x isn't even legal.  K&R A7.4.2 states that
> the operand for the "&" operator must be an lvalue or a function.

Yup. And an array is an lvalue. What it isn't is a modifiable lvalue.

You are allowed to find this confusing. It is.

Richard



Sat, 22 May 2004 02:01:20 GMT  
 Array delarator an lvalue?

Quote:

>Someone pointed out to me recently that given:

>char x[10];

>&x == x is true.

>I would have thought that &x isn't even legal.  K&R A7.4.2 states that
>the operand for the "&" operator must be an lvalue or a function.  GCC
>2.95.3, at least, like it.

The ``lvalueness'' is an expression's inherited attribute that
is derived from whether or not the expression designates an object,
as well as the context in which it appears, and its type. To compute
whether something is an lvalue, we can pretend initially that it's an
lvalue strictly based on its nature, and then remove or preserve that
property based on immediate context.

Consider

        char x[10];

        x[1] = 'a';

What is 'x' in the x[1] expression? Lvalue or not? Since it designates
an object, we initially suppose that it is an lvalue. Then we look at
the type and relevant context: it's an array-type expresion that does not
appear as the operand of a & or sizeof operator. Aha, so it's not an
lvalue after all: it's a non-lvalue expression of type char * which
produces a pointer to the first element of the array.

In your example, the array-designating expression *is* the subject of
the & operator, and so retains its lvalue status in that context.



Sat, 22 May 2004 06:38:38 GMT  
 Array delarator an lvalue?

Quote:


>> Someone pointed out to me recently that given:

>> char x[10];

>> &x == x is true.

>> I would have thought that &x isn't even legal.  K&R A7.4.2 states that
>> the operand for the "&" operator must be an lvalue or a function.  GCC
>> 2.95.3, at least, like it.

>The array IS an lvalue. It just isn't a modifiable one

All the contexts in which an array expresion is an lvalue (operand of
sizeof and operand of & address-of) its modifiability doesn't matter,
because it's not being modified.

In the absence of these operators, an array produces a non-lvalue pointer
to the first element, and is not an lvalue, modifiable or otherwise.



Sat, 22 May 2004 06:42:34 GMT  
 Array delarator an lvalue?

Quote:



>>> Someone pointed out to me recently that given:

>>The array IS an lvalue. It just isn't a modifiable one

>All the contexts in which an array expresion is an lvalue (operand of
>sizeof and operand of & address-of) its modifiability doesn't matter,
>because it's not being modified.

True, but still an array is officially a nonmodifiable lvalue, from
6.3.2.1 (1)

Quote:
>In the absence of these operators, an array produces a non-lvalue pointer
>to the first element, and is not an lvalue, modifiable or otherwise.

If I read the standard right the array is /converted/ to a non-lvalue
which points to its first element, its not one itself. 6.3.2.1 (3)
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>


Sat, 22 May 2004 07:01:54 GMT  
 Array delarator an lvalue?

Quote:





>>>> Someone pointed out to me recently that given:

>>>The array IS an lvalue. It just isn't a modifiable one

>>All the contexts in which an array expresion is an lvalue (operand of
>>sizeof and operand of & address-of) its modifiability doesn't matter,
>>because it's not being modified.

>True, but still an array is officially a nonmodifiable lvalue, from
>6.3.2.1 (1)

>>In the absence of these operators, an array produces a non-lvalue pointer
>>to the first element, and is not an lvalue, modifiable or otherwise.

>If I read the standard right the array is /converted/ to a non-lvalue
>which points to its first element, its not one itself. 6.3.2.1 (3)

It's not the only conversion that takes place during translation. For
example, in the expression a[i],  the ``a'' starts out as a preprocessor
token, then is converted to an identifier, which is then recognizes as
a primary expression having array type, which is then converted into a
pointer to the first element which is not an lvalue.

So we could also say that the preprocessor token ``a'' is only converted
to a token, it's not one itself. Or that the token is converted to a
primary expression, and is not one itself.  Because translation is divided
into phases, we can identify a phase in which ``a'' is a preprocessor
token and one in which it is a token; the division into phases allows
you to make these statements. Because in fact until a certain translation
phase is reached, ``a'' is merely a preprocessor token.

However, the conversions of ``a'' to an array expression and then to
a pointer expression are part of the same translation phase. So this
sequence of conversions is not multiple steps, but really one logical
step. You can't divide a translation phase into sub-phases without
abandoning the standard and dividing into an implementation debate.



Sat, 22 May 2004 08:27:48 GMT  
 Array delarator an lvalue?

Quote:

>However, the conversions of ``a'' to an array expression and then to
>a pointer expression are part of the same translation phase. So this
>sequence of conversions is not multiple steps, but really one logical
>step. You can't divide a translation phase into sub-phases without
>abandoning the standard and dividing into an implementation debate.

For sure,  but I'm merely reading the standard, which explicitly says
that an array is converted to a pointer-to-first-element which is not
an lvalue, while contrariwise it does not say that an array is
converted to anything when the operand of sizeof. I think the
conversion you are discussing above is somewhat different - converting
a textual token into an in-memory reference.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>



Sat, 22 May 2004 08:48:39 GMT  
 Array delarator an lvalue?

Quote:





> >>> Someone pointed out to me recently that given:

> >>The array IS an lvalue. It just isn't a modifiable one

> >All the contexts in which an array expresion is an lvalue (operand of
> >sizeof and operand of & address-of) its modifiability doesn't matter,
> >because it's not being modified.

> True, but still an array is officially a nonmodifiable lvalue, from
> 6.3.2.1 (1)

> >In the absence of these operators, an array produces a non-lvalue pointer
> >to the first element, and is not an lvalue, modifiable or otherwise.

> If I read the standard right the array is /converted/ to a non-lvalue
> which points to its first element, its not one itself. 6.3.2.1 (3)

<rant>
Who is to blame for this non-modifiable lvalue nonsense? I want his
name! I shall burn him in effigy (I hope it's not DMR). An lvalue should
be an expression of an object that one can assign to. So given 'int
array[10];' by what rationale is array an lvalue? Apparently lvalue has
now decayed to an expression of any object, assignable or not. Oops!
Deja vu? Did we work this out 10 years ago? What was the answer?
</rant>

--

"Everything should be made as simple as possible, but not simpler."
                    --- Albert Einstein ---



Sat, 22 May 2004 09:32:09 GMT  
 Array delarator an lvalue?

Quote:

> <rant>
> Who is to blame for this non-modifiable lvalue nonsense? I want his
> name! I shall burn him in effigy (I hope it's not DMR). An lvalue should
> be an expression of an object that one can assign to. So given 'int
> array[10];' by what rationale is array an lvalue? Apparently lvalue has
> now decayed to an expression of any object, assignable or not. Oops!
> Deja vu? Did we work this out 10 years ago? What was the answer?
> </rant>

Makes a great lead-in to my own rant, on the notion that the result of a cin
in C++ should be an lvalue, hence:

  cArr << cin;

instead of the (no more beneficial, and much more irregular):

  cin >> cArr;

Bill



Sat, 22 May 2004 13:16:58 GMT  
 Array delarator an lvalue?

Quote:

> Someone pointed out to me recently that given:

> char x[10];

> &x == x is true.

> I would have thought that &x isn't even legal.  K&R A7.4.2 states that
> the operand for the "&" operator must be an lvalue or a function.  GCC
> 2.95.3, at least, like it.

> Greg

Of course it is equal and is guaranteed to be equal C has got its
roots in B which had the expressions like *(array_name + i )  to give
some of the element corresponding to array_name[i]. There are
certainly advantages in this approach consider
int array[4];
int (*arrayptr)[4] = &array;

Personally I think the most confusing part is that of the use of
sizeof ( & array ) == sizeof( array ); I would have suggested that we
have
sizeof( array ) == sizeof ( int *);
and sizeof( &array ) == sizeof(int) * 4;



Sat, 22 May 2004 14:27:22 GMT  
 Array delarator an lvalue?

Quote:

<snip>

> Personally I think the most confusing part is that of the use of
> sizeof ( & array ) == sizeof( array );

Whatever gave you that idea?

#include <stdio.h>

int main(void)
{
  int foo[56];
  printf("%d\n", (int)sizeof foo);
  printf("%d\n", (int)sizeof &foo);
  return 0;

Quote:
}

This shows that foo and &foo have completely different sizes. If they
give you the same size, you have a really weird system, where pointers
are 56*sizeof(int) bytes wide.

Quote:
> I would have suggested that we
> have
> sizeof( array ) == sizeof ( int *);

Why?

Quote:
> and sizeof( &array ) == sizeof(int) * 4;

Why? And what's so magical about 4?

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Sat, 22 May 2004 17:50:17 GMT  
 Array delarator an lvalue?


Quote:


>> Someone pointed out to me recently that given:

>> char x[10];

>> &x == x is true.

>> I would have thought that &x isn't even legal.  K&R A7.4.2 states that
>> the operand for the "&" operator must be an lvalue or a function.  GCC
>> 2.95.3, at least, like it.

>> Greg

>Of course it is equal and is guaranteed to be equal

&x == x is not a valid expression in C. x and &x have different types
that cannot be compared directly. They point to different objects,
x points to a char object and &x points to an object that is an array
of 10 chars so conceptually they are significantly different pointers.
So the concept of whether they are equal or not makes little sense in C.

What you can say is that they point to objects whose first bytes
share the same address, e.g. (void *)x == (void *)&x or here
(char *)&x == x

...

Quote:
>Personally I think the most confusing part is that of the use of
>sizeof ( & array ) == sizeof( array );

It isn't. sizeof(&array) is the sizeof a pointer to the array, sizeof(array)
is the size of the array itself.

Quote:
>I would have suggested that we
>have
>sizeof( array ) == sizeof ( int *);

How could I find out the size of the array if sizeof(array) doesn't do it?
Knowing the size of the array is usually much more useful than knowing
the size of a pointer. I could get the latter using, say, sizeof(array+0)

Quote:
>and sizeof( &array ) == sizeof(int) * 4;

What is the significance of 4 ints?

--
-----------------------------------------


-----------------------------------------



Sat, 22 May 2004 20:44:35 GMT  
 Array delarator an lvalue?


Quote:

>>char x[10];

>>&x == x is true.

>>I would have thought that &x isn't even legal.  K&R A7.4.2 states that
>>the operand for the "&" operator must be an lvalue or a function.  GCC
>>2.95.3, at least, like it.

>The ``lvalueness'' is an expression's inherited attribute that
>is derived from whether or not the expression designates an object,
>as well as the context in which it appears, and its type. To compute
>whether something is an lvalue, we can pretend initially that it's an
>lvalue strictly based on its nature, and then remove or preserve that
>property based on immediate context.

C99 throws that out of the window. It says simply

"An lvalue is an expression with an object type or an incomplete type
 other than void;"

However the whole area of lvalueness is hopelessly broken in C99 so
it is probably best ignored. :-)

Quote:
>Consider

>        char x[10];

>        x[1] = 'a';

>What is 'x' in the x[1] expression? Lvalue or not?

Yes, x is an lvalue.

Quote:
>Since it designates
>an object, we initially suppose that it is an lvalue. Then we look at
>the type and relevant context: it's an array-type expresion that does not
>appear as the operand of a & or sizeof operator. Aha, so it's not an
>lvalue after all: it's a non-lvalue expression of type char * which
>produces a pointer to the first element of the array.

The value of x (which is an lvalue) is in this context converted to a
pointer valu that is not an lvalue. This is a real step in the evaluation
process of the abstract machine as the standard defines it.

--
-----------------------------------------


-----------------------------------------



Sat, 22 May 2004 20:55:30 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. a macro that uses ( ? : ) conditional as an lvalue

2. LValue problem

3. Resulting lvalue of assignment operation

4. expression return value / lvalue

5. (lvalue)

6. lvalue in C

7. lvalue

8. Lvalue required in function main ?

9. lvalues and increment operator

10. LValue problems

11. ISO C forbids use of cast expressions as lvalues

12. modify const-qual obj via const-qual lvalue?

 

 
Powered by phpBB® Forum Software