Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Difference between these pointer syntaxes Date: Sat, 27 Aug 2016 23:37:45 -0700 Organization: None to speak of Lines: 60 Message-ID: References: <4628cd2d-9333-4be6-943a-eb593c5c4c12@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="945944de09706c9b4e29b53c9d2efdc2"; logging-data="9634"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19GbDEHl7rh2TXuWsHGeWis" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:vU+1XN77qYMVL+5pc8kDJbm+/b0= sha1:MFEB6lGpSxvn5wGcje3sCq3Wm5I= Xref: csiph.com comp.lang.c:92838 Tim Rentsch writes: > Keith Thompson writes: > >> [...] >> >> In fact *all* expressions of array type are lvalues (I'm not quite >> 100% certain of that). You need to enumerate the three exceptions >> to determine when they are and are not converted to pointers. >> >> (One corner case is an array member of a struct or union value >> that is the result of a function call. C11 added the concept of >> "temporary lifetime" to account for this.) > > Temporary lifetime has no effect on lvalue-ness. A non-lvalue > expression of a struct or union type that has an array member > may be used to select that member with '.' to produce an > expression of array type that is not an lvalue. I find the standard's wording in this area a bit odd. N1570 6.2.4p8: A non-lvalue expression with structure or union type, where the structure or union contains a member with array type (including, recursively, members of all contained structures and unions) refers to an object with automatic storage duration and *temporary lifetime*. So it's a non-lvalue expression, but it refers to an object. An lvalue is by definition "an expression (with an object type other than void) that potentially designates an object". Do "refers to" and "designates" mean different things? Perhaps the idea is that such an expression always undergoes *lvalue conversion* (6.3.2.1p2), which makes it no longer an lvalue. This requires more thought. > Using struct-returning functions is one way to do this. There > are a few others. I believe they all rely on having an array > member of a struct or union. I've thought of several cases other than function calls. You can have a non-lvalue expression of structure or union type with an assignment, a comma operator, or a conditional operator. #include int main(void) { struct foo { int arr[10]; }; struct foo x = { 0 }, y = { 0 }; printf("%d\n", (y = x).arr[0]); printf("%d\n", (y, x).arr[0]); printf("%d\n", (1 ? y : x).arr[0]); } -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"