Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Array delarator an lvalue?

13 views
Skip to first unread message

Greg Rickard

unread,
Dec 3, 2001, 12:46:53 PM12/3/01
to
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

Joona I Palaste

unread,
Dec 3, 2001, 12:50:21 PM12/3/01
to
Greg Rickard <greg.r...@amd.com> scribbled the following:

> char x[10];

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

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| 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

Gergo Barany

unread,
Dec 3, 2001, 12:58:53 PM12/3/01
to
Greg Rickard <greg.r...@amd.com> wrote:
> 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.

> 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"

Richard Bos

unread,
Dec 3, 2001, 1:01:20 PM12/3/01
to
greg.r...@amd.com (Greg Rickard) wrote:

> 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

Kaz Kylheku

unread,
Dec 3, 2001, 5:38:38 PM12/3/01
to

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.

Kaz Kylheku

unread,
Dec 3, 2001, 5:42:34 PM12/3/01
to
In article <9uge0t$cnf$1...@oravannahka.helsinki.fi>, Joona I Palaste wrote:
>Greg Rickard <greg.r...@amd.com> scribbled the following:
>> 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.

Mark McIntyre

unread,
Dec 3, 2001, 6:01:54 PM12/3/01
to
On Mon, 03 Dec 2001 22:42:34 GMT, k...@ashi.footprints.net (Kaz
Kylheku) wrote:

>In article <9uge0t$cnf$1...@oravannahka.helsinki.fi>, Joona I Palaste wrote:
>>Greg Rickard <greg.r...@amd.com> scribbled the following:
>>> 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)
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>

Kaz Kylheku

unread,
Dec 3, 2001, 7:27:48 PM12/3/01
to

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.

Mark McIntyre

unread,
Dec 3, 2001, 7:48:39 PM12/3/01
to

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.

Joe Wright

unread,
Dec 3, 2001, 8:32:09 PM12/3/01
to

<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>

--
Joe Wright mailto:joeww...@earthlink.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

William Meyer

unread,
Dec 4, 2001, 12:16:58 AM12/4/01
to
"Joe Wright" <joeww...@earthlink.net> wrote in message
news:3C0C27...@earthlink.net...

>
> <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


Imanpreet Singh Arora

unread,
Dec 4, 2001, 1:27:22 AM12/4/01
to
greg.r...@amd.com (Greg Rickard) wrote in message news:<4ee8cbfe.0112...@posting.google.com>...

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;

Richard Heathfield

unread,
Dec 4, 2001, 4:50:17 AM12/4/01
to
Imanpreet Singh Arora wrote:
>
<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;
}

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.

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

Why?

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

Why? And what's so magical about 4?

--
Richard Heathfield : bin...@eton.powernet.co.uk
"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


Lawrence Kirby

unread,
Dec 4, 2001, 7:44:35 AM12/4/01
to
In article <63bf9a42.01120...@posting.google.com>

imano...@yahoo.com "Imanpreet Singh Arora" writes:

>greg.r...@amd.com (Greg Rickard) wrote in message
> news:<4ee8cbfe.0112...@posting.google.com>...
>> 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

...

>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.

>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)

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

What is the significance of 4 ints?

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

Lawrence Kirby

unread,
Dec 4, 2001, 7:55:30 AM12/4/01
to
In article <O9TO7.18919$nm3.8...@news1.rdc1.bc.home.com>
k...@ashi.footprints.net "Kaz Kylheku" writes:

>In article <4ee8cbfe.0112...@posting.google.com>, Greg Rickard wrote:>>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.

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. :-)

>Consider
>
> char x[10];
>
> x[1] = 'a';
>
>What is 'x' in the x[1] expression? Lvalue or not?

Yes, x is an lvalue.

>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.

Lawrence Kirby

unread,
Dec 4, 2001, 8:01:37 AM12/4/01
to
In article <8MUO7.19233$nm3.8...@news1.rdc1.bc.home.com>
k...@ashi.footprints.net "Kaz Kylheku" writes:

...

>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.

This is nothing to do with translation phases, it is part of the process
of expression evaluation in the abstract machine. This is inherently a
stepwise process e.g. in the expression array[1+2L] there is a sequence
of steps

1. 2 and 3L are expressions of type int and long respectively, array
is an lvalue expression of array type (at least 4 element long)

2. The usual arithmetic conversions are applied to the operands of + and
as a consequence 1 is converted to long

3. (long)1 is added to 2L to produce the result 3 with type long

4. as an operand of [] the lvalue array is converted to a pointer to its


first element which is not an lvalue.

5. [] is applied to its operands, the pointer value derived from array and
the result of the + operator, to produce an lvalue designating the 4th
element of array.


4. is a clear step in this process. Other orders are possible, step 4. can
precede 3. or 2.

Step 2 is another example of an implicit conversion based on context.

Imanpreet Singh Arora

unread,
Dec 5, 2001, 12:02:32 AM12/5/01
to
Richard Heathfield <bin...@eton.powernet.co.uk> wrote in message news:<3C0C9C59...@eton.powernet.co.uk>...

> Imanpreet Singh Arora wrote:
> >
> <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;
> }
>
> 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.
#include <stdio.h>

int main(void)
{
int foo[56];

int x,y;
printf("%d\n",x= (int)sizeof foo);
printf("%d\n",y = (int)sizeof &foo);
if ( x == y )
printf( " I have A really Wierd system");
return 0;
}

F:\cprogra# testarr
224
224
I have A really Wierd system


>
> > I would have suggested that we
> > have
> > sizeof( array ) == sizeof ( int *);
>
> Why?
>
> > and sizeof( &array ) == sizeof(int) * 4;
>
> Why? And what's so magical about 4?

int array[4];


int (*arrayptr)[4] = &array;

Was what I wrote in the first post.

Richard Heathfield

unread,
Dec 5, 2001, 3:40:07 AM12/5/01
to

It's more likely that you have a broken compiler. If it's any
consolation, I've found that Turbo C is similarly broken. gcc, of
course, does the Right Thing.

>
> >
> > > I would have suggested that we
> > > have
> > > sizeof( array ) == sizeof ( int *);
> >
> > Why?
> >
> > > and sizeof( &array ) == sizeof(int) * 4;
> >
> > Why? And what's so magical about 4?
>
> int array[4];
> int (*arrayptr)[4] = &array;
> Was what I wrote in the first post.

Thanks for clarifying. There's no particular reason for sizeof &array to
be equal to sizeof(int) * 4.

Imanpreet Singh Arora

unread,
Dec 5, 2001, 10:00:55 AM12/5/01
to
Richard Heathfield <bin...@eton.powernet.co.uk> wrote in message news:<3C0DDD67...@eton.powernet.co.uk>...

This is really strange Visual C++ 7.0( Which gives me a "??" on every
illegal instruction or pointer refference :) ), Borland 5.5 too give
the same result Are all compilers broken on this very issue except of
course the one that you are mentioning gcc.

CBFalconer

unread,
Dec 5, 2001, 12:31:06 PM12/5/01
to
Richard Heathfield wrote:
> Imanpreet Singh Arora wrote:
> > Richard Heathfield <bin...@eton.powernet.co.uk> wrote in message

Many systems are "helpful" in that they discard an & before an
array name because the normal purpose is to do what comes
naturally (or unnaturally, depending on point of view). A
parentheses as in &(foo) might do the trick for those. They
should at least emit a warning "& of array discarded" or some such
verbiage. He may have an insufficient warning level. Of course
the compiler is still broken.

--
Chuck F (cbfal...@yahoo.com) (cbfal...@XXXXworldnet.att.net)
Available for consulting/temporary embedded and systems.
(Remove "XXXX" from reply address. yahoo works unmodified)
mailto:u...@ftc.gov (for spambots to harvest)


Richard Heathfield

unread,
Dec 5, 2001, 12:07:17 PM12/5/01
to
Imanpreet Singh Arora wrote:
>
<snip discussion on whether sizeof &array == sizeof array>

>
> This is really strange Visual C++ 7.0( Which gives me a "??" on every
> illegal instruction or pointer refference :) ), Borland 5.5 too give
> the same result Are all compilers broken on this very issue except of
> course the one that you are mentioning gcc.

I'd be very surprised if *all* C compilers (except for gcc) are broken
in this way. Nevertheless, it would appear that your compilers are
indeed broken.

Lawrence Kirby

unread,
Dec 11, 2001, 11:52:01 AM12/11/01
to
In article <3C0C27...@earthlink.net>
joeww...@earthlink.net "Joe Wright" writes:

...

><rant>
>Who is to blame for this non-modifiable lvalue nonsense? I want his
>name!

Probably a standardisation thing so you can blame it on a committee. :-)

>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?

It designates an object. Unfortunately C exposes the principle of
objects that can't be modified so the concept of an object and
something that can be written to are no longer the same.

>Apparently lvalue has
>now decayed to an expression of any object, assignable or not. Oops!

That's why a footnote suggests you think of lvalue meaning "locator value".

>Deja vu? Did we work this out 10 years ago? What was the answer?
></rant>

The "answer" is what ws put in the standard. It has degenerated even
further in C99. :-)

Lawrence Kirby

unread,
Dec 11, 2001, 11:30:39 AM12/11/01
to
In article <3C0E4CEC...@yahoo.com>
cbfal...@worldnet.att.net "CBFalconer" writes:

...

>Many systems are "helpful" in that they discard an & before an
>array name because the normal purpose is to do what comes
>naturally (or unnaturally, depending on point of view).

Some pre-standard compilers did this, but it is severely broken behaviour
for a standard C compiler. I hope "Many" above isn't supposed to refer
to standard compilers.

Joe Wright

unread,
Dec 11, 2001, 10:31:54 PM12/11/01
to
Lawrence Kirby wrote:
>
> In article <3C0C27...@earthlink.net>
> joeww...@earthlink.net "Joe Wright" writes:
>
> ...
>
> ><rant>
> >Who is to blame for this non-modifiable lvalue nonsense? I want his
> >name!
>
> Probably a standardisation thing so you can blame it on a committee. :-)
>
> >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?
>
> It designates an object. Unfortunately C exposes the principle of
> objects that can't be modified so the concept of an object and
> something that can be written to are no longer the same.
>
> >Apparently lvalue has
> >now decayed to an expression of any object, assignable or not. Oops!
>
> That's why a footnote suggests you think of lvalue meaning "locator value".
>
> >Deja vu? Did we work this out 10 years ago? What was the answer?
> ></rant>
>
> The "answer" is what ws put in the standard. It has degenerated even
> further in C99. :-)
>
I guess it's just nostalgia. Old habits die hard. K&R1 said clearly that
an object was a manipulatable region of storage and that an lvalue was
an expression referring to an object. I liked it that way.

But why? Given 'char arr[10];', why would you consider arr an object? It
is an array of objects, not an object itself. If it were an object we
could pass its 'value' to functions or whatever. We cannot. On the other
hand, I can ignore new 'unmodifiable lvalue' stuff in my own belief that
arr is NOT an lvalue or an object in itself. Peace.

Kaz Kylheku

unread,
Dec 11, 2001, 10:57:15 PM12/11/01
to
In article <3C0C27...@earthlink.net>, Joe Wright wrote:
>Mark McIntyre wrote:
>>
>> On Mon, 03 Dec 2001 22:42:34 GMT, k...@ashi.footprints.net (Kaz
>> Kylheku) wrote:
>>
>> >In article <9uge0t$cnf$1...@oravannahka.helsinki.fi>, Joona I Palaste wrote:
>> >>Greg Rickard <greg.r...@amd.com> scribbled the following:
>> >>> 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?

By rationale that you can take its address. That's the other special
thing you can do with lvalue. Arrays that are evaluated are not
in fact lvalues, they are non-lvalue pointers to the first element.

One way to determine the lvalue property of arrays is to first consider
them to be lvalues and then take that away based on context, but it doesn't
have to be done that way, and the process is not visible because it
is all part of the one translation phase.

The net effect is that arrays are sometimes lvalues and sometimes not.

pete

unread,
Dec 12, 2001, 9:40:56 AM12/12/01
to
Kaz Kylheku wrote:
>
> In article <3C0C27...@earthlink.net>, Joe Wright wrote:
> >

> > by what rationale is array an lvalue?
>
> By rationale that you can take its address. That's the other special
> thing you can do with lvalue. Arrays that are evaluated are not
> in fact lvalues, they are non-lvalue pointers to the first element.

You can't take the address of a register variable, but
a register variable is an object.
You can take the address of a function name
the same way as you can for an array name, but
a function isn't an object and an array is.

* Object --- a region of data storage in the execution environment,
the contents of which can represent values. Except for bit-fields,
objects are composed of contiguous sequences of one or more bytes,
the number, order, and encoding of which are either explicitly
specified or implementation-defined.

... and if you try to generalize beyond that, then
it just gets confusing.

--
pete

Lawrence Kirby

unread,
Dec 19, 2001, 11:34:08 AM12/19/01
to
In article <3C16D0...@earthlink.net>
joeww...@earthlink.net "Joe Wright" writes:

...

>I guess it's just nostalgia. Old habits die hard. K&R1 said clearly that


>an object was a manipulatable region of storage and that an lvalue was
>an expression referring to an object. I liked it that way.
>
>But why? Given 'char arr[10];', why would you consider arr an object?

It is a manipulable region of storage. Fundamentally it is something
that can store state with a degree of persistence.

>It
>is an array of objects, not an object itself.

It groups those sub-objects into a unit that can be considered as a single
entity. That's important for array indexing (pointer arithmetic), allocating
the array e.g. defining the object or with malloc() and performing
object-wide operations on it using e.g. memcpy() or fwrite().

>If it were an object we
>could pass its 'value' to functions or whatever. We cannot.

The fact that C lacks a certain degree of syntactic sugar shouldn't IMO
affect the status of an object. If you accept that structures are objects
then I would find it difficult to justify saying that arrays aren't.
Yes, I can assign whole structures but again that is just syntactic sugar.
I can achieve the same thing easily enough with arrays using memcpy().

>On the other
>hand, I can ignore new 'unmodifiable lvalue' stuff in my own belief that
>arr is NOT an lvalue or an object in itself. Peace.

I'd find it odd to be able to take the address of something that isn't
an object and I can take the address of an array as a whole.

Joe Wright

unread,
Dec 19, 2001, 2:01:28 PM12/19/01
to
I think you have clearly understood me. You just can't make yourself say
what I say, namely that an lvalue refers to an object and that an object
must be modifiable.

char arr[10];

Because we can't do 'arr = ...;', arr cannot be an lvalue. But it might
be an object to the extent that you can modify its elements, but you
can't modify it.

Pai-Yi HSIAO

unread,
Dec 20, 2001, 8:55:06 AM12/20/01
to
On Wed, 19 Dec 2001, Joe Wright wrote:
> I think you have clearly understood me. You just can't make yourself say
> what I say, namely that an lvalue refers to an object and that an object
> must be modifiable.
>
> char arr[10];
> Because we can't do 'arr = ...;', arr cannot be an lvalue.

The standard never says an lvalue must be allowed to do assignment
like "arr = ...;".
Think about a const-qualified lvalue.
It's why in 6.3.2.1 the standard defines what "modifiable lvalue" is.

arr is an array of objects and ALSO is an array object. (6.5.2.1#2).

The standard never requires the value of an object is able to be passed
into a function.
You can not prove arr is not an object by saying its value can not be
passed to function via arr.

paiyi

Lawrence Kirby

unread,
Dec 20, 2001, 10:49:25 AM12/20/01
to
In article <3C20E5...@earthlink.net>
joeww...@earthlink.net "Joe Wright" writes:

...

>I think you have clearly understood me. You just can't make yourself say


>what I say, namely that an lvalue refers to an object and that an object
>must be modifiable.

Because I'm comfortable with the idea of a non-modifiable object.
I'm happy with an object being a region of memory, that can represent
values. I'm happy that ROM is a form of memory a C implementation could
store objects in ROM if their values never change.

>char arr[10];
>
>Because we can't do 'arr = ...;', arr cannot be an lvalue.

The problem with this is historical. The derivation of lvalue is from
"left value" i.e. something that can appear on the left hand side of
an assignment. In C its usage is different, it is used to mean an
"object designator" (cf. the standard term "function designator")
which is a more useful concept in C. I suppose the standard could
have been written to use terminology differently e.g. use the term
"object designator" where it uses lvalue now, and define an lvalue
to be a modifiable object designator. However "object designator"
is a bit of a mouthfull. :-)

>But it might
>be an object to the extent that you can modify its elements, but you
>can't modify it.

You modify it through its element. C just happens to lack the syntax
to modify it as a single entity.

0 new messages