Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #13739 > unrolled thread
| Started by | Joe Wright <joewwright@comcast.net> |
|---|---|
| First post | 2011-11-21 16:25 -0500 |
| Last post | 2012-01-25 05:00 -0800 |
| Articles | 18 on this page of 78 — 15 participants |
Back to article view | Back to comp.lang.c
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Size of an arraylist in bytes Joe Wright <joewwright@comcast.net> - 2011-11-21 16:25 -0500
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2011-11-21 14:03 -0800
Re: Size of an arraylist in bytes pete <pfiland@mindspring.com> - 2011-11-21 17:45 -0500
Re: Size of an arraylist in bytes Ark <akhasin@macroexpressions.com> - 2011-11-21 21:19 -0500
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-21 22:06 -0500
Re: Size of an arraylist in bytes Ark <akhasin@macroexpressions.com> - 2011-11-22 03:07 -0500
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2011-11-22 06:51 -0500
Re: an instance of an object (was: Size of an arraylist in bytes) Keith Thompson <kst-u@mib.org> - 2011-11-21 21:54 -0800
Re: Size of an arraylist in bytes pete <pfiland@mindspring.com> - 2011-11-22 01:49 -0500
Re: Size of an arraylist in bytes Ark <akhasin@macroexpressions.com> - 2011-11-22 03:17 -0500
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2011-11-22 00:48 -0800
Re: Size of an arraylist in bytes pete <pfiland@mindspring.com> - 2011-11-23 05:16 -0500
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2011-11-22 16:49 +0000
Re: Size of an arraylist in bytes pete <pfiland@mindspring.com> - 2011-11-23 09:30 -0500
Re: Size of an arraylist in bytes Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-11-22 00:07 -0800
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2011-11-22 00:24 -0800
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 05:06 -0800
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2012-01-25 12:15 -0800
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 18:49 -0800
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2012-02-01 13:53 -0800
Re: Size of an arraylist in bytes lawrence.jones@siemens.com - 2012-02-01 18:53 -0500
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2012-02-01 20:06 -0800
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-01 21:40 -0500
Re: Size of an arraylist in bytes jgk@panix.com (Joe keane) - 2012-02-02 03:45 +0000
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2012-02-01 20:14 -0800
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-01 23:14 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-02 18:38 -0500
Re: Size of an arraylist in bytes jgk@panix.com (Joe keane) - 2012-02-03 16:32 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-03 11:57 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-03 20:07 -0500
Re: Size of an arraylist in bytes jgk@panix.com (Joe keane) - 2012-02-04 22:35 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-04 18:43 -0500
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-05 01:50 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-04 21:37 -0500
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-05 14:48 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-05 10:20 -0500
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-05 16:25 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-05 12:06 -0500
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-05 19:21 +0000
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 15:29 -0500
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 10:46 -0800
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-05 02:39 +0000
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-05 15:17 +0000
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-05 12:06 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 15:06 -0500
Re: Size of an arraylist in bytes jgk@panix.com (Joe keane) - 2012-02-07 17:35 +0000
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-07 19:51 -0500
Re: Size of an arraylist in bytes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-08 01:14 +0000
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-05 02:31 +0000
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-03 21:26 -0500
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-03 21:31 -0500
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-04 06:57 -0500
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-04 18:32 +0000
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 22:51 -0500
Re: Size of an arraylist in bytes jgk@panix.com (Joe keane) - 2012-02-04 21:25 +0000
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-04 17:08 -0500
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 10:52 -0800
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-04 17:32 -0500
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-05 02:19 +0000
Re: Size of an arraylist in bytes Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-05 09:20 -0500
Re: Size of an arraylist in bytes James Kuyper <jameskuyper@verizon.net> - 2012-02-05 09:42 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 16:17 -0500
Re: Size of an arraylist in bytes Zoltan Kocsi <zoltan@bendor.com.au> - 2012-02-05 17:49 +1100
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 16:48 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-05 16:52 -0500
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-02 01:07 -0500
Re: Size of an arraylist in bytes lawrence.jones@siemens.com - 2012-02-03 11:29 -0500
Re: Size of an arraylist in bytes Keith Thompson <kst-u@mib.org> - 2012-02-03 12:42 -0800
lvalue "potentially" designates an object (was Re: Size of an arraylist in bytes) Kenneth Brody <kenbrody@spamcop.net> - 2012-02-04 12:47 -0500
Re: lvalue "potentially" designates an object (was Re: Size of an arraylist in bytes) Kaz Kylheku <kaz@kylheku.com> - 2012-02-04 18:39 +0000
Re: Size of an arraylist in bytes lawrence.jones@siemens.com - 2012-02-04 14:46 -0500
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-03 22:35 +0000
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-06 00:01 -0500
Re: Size of an arraylist in bytes Kaz Kylheku <kaz@kylheku.com> - 2012-02-06 08:46 +0000
Re: Size of an arraylist in bytes Shao Miller <sha0.miller@gmail.com> - 2012-02-06 23:17 -0500
Re: Size of an arraylist in bytes lawrence.jones@siemens.com - 2012-02-01 18:34 -0500
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 10:54 -0800
Re: Size of an arraylist in bytes Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 05:00 -0800
Page 4 of 4 — ← Prev page 1 2 3 [4]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-05 09:42 -0500 |
| Message-ID | <jgm4h3$tle$1@dont-email.me> |
| In reply to | #16720 |
On 02/05/2012 09:20 AM, Eric Sosman wrote:
> On 2/4/2012 9:19 PM, Kaz Kylheku wrote:
>> On 2012-02-04, James Kuyper<jameskuyper@verizon.net> wrote:
>>> On 02/04/2012 04:25 PM, Joe keane wrote:
>>> ...
>>>> int g(int x)
>>>> {
>>>> int a[4][5];
>>>> int *p;
>>>> int *q;
>>>> int j;
>>>>
>>>> p =&a[0][5];
>>>> [...]
>>>
>>> Because dereferencing p has undefined behavior, a conforming
>>
>> Says you. There isn't a very convincing case for this in the standard.
>
> Perhaps you've overlooked the final sentence of 6.5.6p8:
>
> "If the result points one past the last element of the array
> object, it shall not be used as the operand of a unary *
> operator that is evaluated."
And, as Keith has pointed out, Annex J.2 is an informative listing of
the circumstances under which behavior is undefined. One of those items
says:
"An array subscript is out of range, even if an object is apparently
accessible with the given subscript (as in the lvalue expression a[1][7]
given the declaration int a[4][5]) (6.5.6)."
While Annex J is only informative, it is consistent with and can be
derived from the normative text of 6.5.6, and makes it clear that it was
intended to be interpreted in this fashions.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-05 16:17 -0500 |
| Message-ID | <jgmrjm$9sl$1@dont-email.me> |
| In reply to | #16720 |
On 2/5/2012 09:20, Eric Sosman wrote:
> On 2/4/2012 9:19 PM, Kaz Kylheku wrote:
>> On 2012-02-04, James Kuyper<jameskuyper@verizon.net> wrote:
>>> On 02/04/2012 04:25 PM, Joe keane wrote:
>>> ...
>>>> int g(int x)
>>>> {
>>>> int a[4][5];
>>>> int *p;
>>>> int *q;
>>>> int j;
>>>>
>>>> p =&a[0][5];
>>>> [...]
>>>
>>> Because dereferencing p has undefined behavior, a conforming
>>
>> Says you. There isn't a very convincing case for this in the standard.
>
> Perhaps you've overlooked the final sentence of 6.5.6p8:
>
> "If the result points one past the last element of the array
> object, it shall not be used as the operand of a unary *
> operator that is evaluated."
>
But that rather depends on what "the array object" is. If "the array
object" is considered to be 'a', then 'p' doesn't point one past that.
--
"The stationery store has moved. Aaargh!"
[toc] | [prev] | [next] | [standalone]
| From | Zoltan Kocsi <zoltan@bendor.com.au> |
|---|---|
| Date | 2012-02-05 17:49 +1100 |
| Message-ID | <20120205174947.18265770@tade.bendor.com.au> |
| In reply to | #16685 |
On Sat, 4 Feb 2012 21:25:00 +0000 (UTC)
jgk@panix.com (Joe keane) wrote:
> How about this:
>
> int g(int x)
> {
[..]
> I'm looking for 'reductio ad absurdum'.
>
> i.e., chapter and verse for 'this can't possibly not work'
It will be undefined behaviour, the great catch-all of C.
I think one shall not try to understand the C standard, at least not why is
it the way it is. Maybe they want to cover every possible (existing or not)
architecture or make C as safe as a managed language, I don't know. If
that's the case, they failed, because it is very easy to shoot yourself in
the foot even when your code is completely standard conforming and it is a
major pain in the neck to write code for anything which does not have a
unified address space, but at least they managed to build robust, insidious
traps into the standard even when you work with a stock-standard, unified,
flat address space machine. They're there to show you that if you thought you
knew C, you should think again. They allow the compiler to generate the
wierdest things, which you'd never thought a sane compiler would ever do and
if you want to report it as a bug, the compiler people will just smirk and
wave the standard.
The 'undefined behaviour' is especially nasty and the standard is full of
them. The standard specifies that undefined behaviour means that when the
compiler detects such a condition, it can do whatever it wants and it does
not have to warn you. Consider this:
print_vector_table_element( void **p )
{
void *e;
e = *p;
if ( p == NULL )
printf( "The reset vector is %p\n", e );
else
printf( "Vector at %p is %%p\n", p, e );
}
Compiling the above with gcc will result in code which does not have the 'if'
and the true branch. Only the 'else' branch remains, unconditionally. The
compiler is right. The e = *p dereferences the pointer. If p was not NULL,
then the else branch is executed. If p was NULL, then the dereferencing is
undefined behaviour and the compiler can do whatever it pleases, including
simpy removing chunks of your code, without as much as issuing a warning (and
indeed, gcc remains silent on the above).
Then there's my personal grudge, the volatile. If you read the standard, it
turns out, that this
volatile int a;
int *p;
while ( a = *p++ ) { ... }
will actually compile into this:
int tmp;
for ( ;; ) {
tmp = *p++;
a = tmp;
tmp = a;
if ( ! tmp ) break;
...
}
because the standard, prior C11, said that the value of the assignment
expression is the value of its lhs after the assignment. Thus, gcc reads back
the volatile to get the value after the assignment, which with write-only HW
registers is kind of a problem; chances are that you wanted to stop after
writing 0 to it, not when its non-existent value becomes 0.
But fair enough, that's what the standard says, stupid programmer to blame.
However, there's a snag, and actually gcc, possibly inadvertedly, breaks the
standard and generates sane code for this supercomplex code fragment:
volatile a;
a = 0;
Let's see what C99 says about that:
- as per 6.8.3.1 a = 0; is an expression statement
- as per 6.8.3.2 it is evaluated as a void expression
- as per 6.3.2.1 a void expression is evaluated for its side effects
- as per 5.1.2.3.2 accessing a volatile object is a side effect
- as per 6.5.16.1 the a = 0 is an assignment expression
- as per 6.5.16.3 its value is the value of the lhs after the assignment
Therefore, a conforming implementation, after writing the 0 to 'a' should read
'a' back and then discard the value. It's a major strike of luck that gcc is
not doing that and one can still write device drivers for memory mapped HW.
Back in around '98 I had an issue with the above behaviour, read the prelim
standard and actually contacted a guy on the committee, suggesting that the
standard to be changed so that the value of an assignment is of type of the
lhs with the value *written* to the lhs. He said that they intentionally left
some ambiguity in the standard (i.e. they did not specify that you do have to
read the value back) to give some flexibility to the compiler people. Alas,
the wording still suggested that you should read the value back.
After a decade with all that uncertainty, finally, C11 got rid of the
ambiguity: the compiler has, unambiguously, an explicit right to generate a
read-back or not, whenever it feels like. Thus, in
while ( a = *p++ ) { ... }
while ( a = *p++ ) { ... }
the compiler may compile the first loop with read-back and the second
without. In fact, it can compile each iteration of each loop with or without a
read-back of a. If it wants, it can read back 'a' depending on the momentary
state of the carry flag or the phase of the moon or anything. The standard
gives a mandate to the compiler to whatever it wants.
Just to make it sure, C11 spells it out even more clearly that a void
expression should have all the side effects of the same expression with its
value being used, that is, an "a=0;" must have its value obtained then
discarded, if such action has a side effect. So that you can be absolutely,
positively sure that you'd not the slightest idea whether there will be a
readback after the write or not.
Gotta luv standards.
Zoltan
--
Zoltán Kócsi
Bendor Research Pty. Ltd.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-05 16:48 -0500 |
| Message-ID | <jgmteo$kh3$1@dont-email.me> |
| In reply to | #16685 |
On 2/4/2012 16:25, Joe keane wrote:
> In article<jgi50h$qp$1@dont-email.me>,
> Eric Sosman<esosman@ieee-dot-org.invalid> wrote:
>> Looks fine to me. But the original went beyond a mere comparison
>> for equality: It tried to store into a[0][5] and beyond, and that's
>> undefined behavior. Strange but true: `*p = 42' is undefined and
>> `*q = 42' is well-behaved, even though `p == q'.
>
> How about this:
>
> int g(int x)
> {
> int a[4][5];
> int *p;
> int *q;
> int j;
>
> p =&a[0][5];
> q =&a[1][0];
> if (p != q)
> barf();
> *p = 2;;
> *q = 3;;
> j = *p;
> if (j != 3)
> puke();
> }
>
> I'm looking for 'reductio ad absurdum'.
>
> i.e., chapter and verse for 'this can't possibly not work'
In fact, 'p' and 'q' can compare as equal and have different object
representations.
int * int_ptr_equ(const int * p, const int * q) {
typedef unsigned char byte;
int * result;
const byte * byte_of_p = (byte *) &p;
const byte * byte_of_q = (byte *) &q;
const byte * byte_of_result = (byte *) &result;
const byte * const one_past_result =
byte_of_result + sizeof result;
while (byte_of_result < one_past_result) {
/* If the object representation differs */
if (*byte_of_p != *byte_of_q) {
/* Then consider them unequal */
return 0;
}
/* Defect report #260: "Provenance" */
*byte_of_result = *byte_of_p & *byte_of_q;
++byte_of_result;
++byte_of_p;
++byte_of_q;
}
/* Return the combined pointers */
return result;
}
Now even if you have:
int g(int x)
{
int a[4][5];
int *p;
int *q;
int *p_and_q;
int j;
p = &a[0][5];
q = &a[1][0];
p_and_q = int_ptr_equ(p, q);
if (!p_and_q)
barf();
/* Trouble on next line */
*p = 2;
*q = 3;
j = *p;
if (j != 3)
puke();
}
You _still_ run into undefined behaviour, as the bounds-checking needn't
be tracked in the pointer's object representation.
However! If, instead, you had:
int g(int x)
{
int a[4][5];
int *p;
int *q;
int *p_and_q;
int j;
p = &a[0][5];
q = &a[1][0];
p_and_q = int_ptr_equ(p, q);
if (!p_and_q)
barf();
/* Next line is ok*/
*p_and_q = 2;
*q = 3;
/* So is this */
j = *p_and_q;
if (j != 3)
puke();
}
I don't know what kind of a case anyone could make for undefined
behaviour. The "provenance" of 'p' and 'q' are both dismissed for the
'p_and_q' pointer. Whether or not 'barf' is called would be
implementation-defined.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-05 16:52 -0500 |
| Message-ID | <jgmtm2$kh3$2@dont-email.me> |
| In reply to | #16732 |
On 2/5/2012 16:48, Shao Miller wrote:
>
> In fact, 'p' and 'q' can compare as equal and have different object
> representations.
>
> int * int_ptr_equ(const int * p, const int * q) {
> typedef unsigned char byte;
> int * result;
> const byte * byte_of_p = (byte *) &p;
> const byte * byte_of_q = (byte *) &q;
> const byte * byte_of_result = (byte *) &result;
> const byte * const one_past_result =
> byte_of_result + sizeof result;
>
Uh, I meant:
byte * const byte_of_result = (byte *) &result;
without the leading 'const'.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-02 01:07 -0500 |
| Message-ID | <jgd96r$pbr$1@dont-email.me> |
| In reply to | #16632 |
On 2/1/2012 22:45, Joe keane wrote:
>> Now I have to read it to find out if there've been any changes in
>> regards to bounds-checking.
>>
>> int a[2][2];
>> int * p =&a[0][3];
>>
>
> So far i know
>
> int d(int x)
> {
> int a[4][5];
> int j;
>
> for (j =0< j< 20; j++)
> {
> a[[0][j] = 0;
> }
>
> ..
> }
>
> is legval C, and if it is not please let me know.
Stepping through the critical [corrected] line 'a[0][j] = 0;', we have:
j -> identifier -> primary-expression -> ... -> expression
0 (both instances) -> constant -> primary-expression -> ... -> expression
a -> identifier -> primary-expression -> ... -> expression
a[0] -> postfix-expression -> ... -> expression
a[0][j] -> postfix-expression -> ... -> expression
a[0][j] = 0 -> assignment-expression -> ... -> expression
a[0][j] = 0; -> expression-statement -> statement
#1 'a' is an "lvalue": an expression that designates an object and has
type 'int[4][5]' as per the declaration.
#2 'a' is not the operand of either 'sizeof' nor of '&', so its
evaluation yields an expression with type 'int(*)[5]' and with value
"pointing to the first element of the array."
#3 'E1[E2]' is identical to '(*((E1)+(E2)))', so...
#4 First we add 0 to the pointer we obtained above (#2). That result
will be an expression with the same type and same value as the original
pointer (#2).
#5 Then we apply the unary indirection '*' operator. Since our pointer
(#4) does point to the first element of the array, an object is
designated and the result has type 'int[5]' and is an lvalue designating
that array object.
#6 Meanwhile 'j' has been evaluated and it has yielded a particular
run-time value with type 'int'.
#7 Just before we apply the '[]' operator, the lvalue we obtained (#5)
that has array type is not the operand or either 'sizeof' nor of '&', so
its evaluation yields an expression with type 'int *' and with value
"pointing to the first element of the array."
#8 Then we apply the second '[]' array subscripting operator.
Considering the identity above, again we first have a pointer (#7) and
an 'int' value (#6) being added together. If the
pointed-to/pointed-into array is large enough, the result will point to
an element of the array, or one element past the final element. If the
pointed-to/pointed-into array is not large enough, the behaviour is
undefined. We need to figure out this result before we can proceed with
application of the unary '*' operator (#3).
So is the array large enough for all the values of 'j' you allowed in
your 'for' loop? Your loop body is allowed to have values of 'j' from 0
through 19. How large is the array object? Well, that depends...
Is the array object the 'int[5]'-typed array designated by the lvalue
from #5? If so, then 'j' can run out of bounds.
Is the array object the 'int[4][5]'-typed array designated by the lvalue
from #1? If so, how many 'int'-typed elements are in that array? 0? 20?
Is the array object a region of data storage with contents that can
represent values for 20 contiguous 'int's and so happens to be suitably
aligned for 20 contiguous 'int's?
If the answers for these questions aren't clearly defined, perhaps
implementations will define the answers according to some particular
interpretation, including "bounds-checking" interpretations which define
your 'j' to go out of bounds.
--
"The stationery store has moved. Aaargh!"
[toc] | [prev] | [next] | [standalone]
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2012-02-03 11:29 -0500 |
| Message-ID | <eketv8-fdf.ln1@jones.homeip.net> |
| In reply to | #16618 |
Keith Thompson <kst-u@mib.org> wrote: > > (An aside: I've complained before that the C90 and C99 standards' > definitions of "lvalue" were flawed, and suggested "expression that > potentially designates an object" to fix the problem. The word > "potentially" is needed to ensure that *ptr is an lvalue even if > ptr==NULL. I just now noticed that N1570 has this updated wording. > Looks like somebody was listening. I am inordinately pleased.) You're welcome. :-) -- Larry Jones Talk about someone easy to exploit! -- Calvin
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-02-03 12:42 -0800 |
| Message-ID | <lnfwerps1t.fsf@nuthaus.mib.org> |
| In reply to | #16664 |
lawrence.jones@siemens.com writes:
> Keith Thompson <kst-u@mib.org> wrote:
>> (An aside: I've complained before that the C90 and C99 standards'
>> definitions of "lvalue" were flawed, and suggested "expression that
>> potentially designates an object" to fix the problem. The word
>> "potentially" is needed to ensure that *ptr is an lvalue even if
>> ptr==NULL. I just now noticed that N1570 has this updated wording.
>> Looks like somebody was listening. I am inordinately pleased.)
>
> You're welcome. :-)
Is there a DR yet asking to clarify what the heck "potentially
designates" means? 8-)}
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2012-02-04 12:47 -0500 |
| Subject | lvalue "potentially" designates an object (was Re: Size of an arraylist in bytes) |
| Message-ID | <FJSdneTzwtbI8rDSnZ2dnUVZ_sSdnZ2d@bestweb.net> |
| In reply to | #16668 |
On 2/3/2012 3:42 PM, Keith Thompson wrote:
> lawrence.jones@siemens.com writes:
>> Keith Thompson<kst-u@mib.org> wrote:
>>> (An aside: I've complained before that the C90 and C99 standards'
>>> definitions of "lvalue" were flawed, and suggested "expression that
>>> potentially designates an object" to fix the problem. The word
>>> "potentially" is needed to ensure that *ptr is an lvalue even if
>>> ptr==NULL. I just now noticed that N1570 has this updated wording.
>>> Looks like somebody was listening. I am inordinately pleased.)
>>
>> You're welcome. :-)
>
> Is there a DR yet asking to clarify what the heck "potentially
> designates" means? 8-)}
Imagine the code:
void foo(int *ptr)
{
(*ptr)++;
}
The "(*ptr)" is obviously an lvalue, yet there is no guarantee that pt is a
valid pointer. (It goes beyond your case of "ptr==NULL".) You can't say
for sure that (*ptr) "designates an object", only that it "potentially"
designates an object. (Whereas, for example, "*(&foo)" is guaranteed to
designate an object.)
On the other hand, "ptr++" can never designate an object, regardless of the
value of anything involved, and is therefore not an lvalue.
While the above certainly isn't Standardese, I think it describes the intent.
Just my 20m$.
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-02-04 18:39 +0000 |
| Subject | Re: lvalue "potentially" designates an object (was Re: Size of an arraylist in bytes) |
| Message-ID | <20120204193424.961@kylheku.com> |
| In reply to | #16680 |
On 2012-02-04, Kenneth Brody <kenbrody@spamcop.net> wrote:
> On 2/3/2012 3:42 PM, Keith Thompson wrote:
>> lawrence.jones@siemens.com writes:
>>> Keith Thompson<kst-u@mib.org> wrote:
>>>> (An aside: I've complained before that the C90 and C99 standards'
>>>> definitions of "lvalue" were flawed, and suggested "expression that
>>>> potentially designates an object" to fix the problem. The word
>>>> "potentially" is needed to ensure that *ptr is an lvalue even if
>>>> ptr==NULL. I just now noticed that N1570 has this updated wording.
>>>> Looks like somebody was listening. I am inordinately pleased.)
>>>
>>> You're welcome. :-)
>>
>> Is there a DR yet asking to clarify what the heck "potentially
>> designates" means? 8-)}
>
> Imagine the code:
>
> void foo(int *ptr)
> {
> (*ptr)++;
> }
>
> The "(*ptr)" is obviously an lvalue, yet there is no guarantee that pt is a
> valid pointer. (It goes beyond your case of "ptr==NULL".) You can't say
> for sure that (*ptr) "designates an object", only that it "potentially"
> designates an object.
See, or you could just say that its syntax, type and context categorize
that expression an lvalue, grammatically. No need to mention objects.
It's an lvalue because it has object type, a syntactic form for an lvalue
(dereference expression) and the right context (operand of increment).
If something doesn't exist, and we talk about it, it is still a noun.
lvalue is purely a grammatic concept.
[toc] | [prev] | [next] | [standalone]
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2012-02-04 14:46 -0500 |
| Message-ID | <8ie009-n0n.ln1@jones.homeip.net> |
| In reply to | #16668 |
Keith Thompson <kst-u@mib.org> wrote: > > Is there a DR yet asking to clarify what the heck "potentially > designates" means? 8-)} No, but if one comes in, I'm sending it to you! -- Larry Jones When I want an editorial, I'll ASK for it! -- Calvin
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-02-03 22:35 +0000 |
| Message-ID | <20120203135041.829@kylheku.com> |
| In reply to | #16664 |
On 2012-02-03, lawrence.jones@siemens.com <lawrence.jones@siemens.com> wrote:
> Keith Thompson <kst-u@mib.org> wrote:
>>
>> (An aside: I've complained before that the C90 and C99 standards'
>> definitions of "lvalue" were flawed, and suggested "expression that
>> potentially designates an object" to fix the problem. The word
>> "potentially" is needed to ensure that *ptr is an lvalue even if
>> ptr==NULL. I just now noticed that N1570 has this updated wording.
>> Looks like somebody was listening. I am inordinately pleased.)
>
> You're welcome. :-)
A very simple, define an lvalue is as an expression which satisfies these three
conditions:
- [lvalue syntactic form] An lvalue is either a certain kind of primary
expression, (identifier or string literal) or its operator falls into a
certain set:
- struct/union member selection (. operator) applied to an expression which
itself has lvalue syntactic form).
- pointer member selection (-> operator)
- pointer dereference or array indexing
If E has the syntactic form of an lvalue, then so does (E) and
denotes the same lvalue as E.
- [lvalue context] An lvalue is the argument of certain operators in certain
positions (those which require lvalues):
- destination operand of assignment
- operand of & address-of
- operand of increment
- ... etc
Expressions not in these contexts are not lvalues even if they have
lvalue syntactic form.
- [lvalue type] An lvalue has object type.
Further, lvalues are then classified as modifiable if they are not array types,
and not const-qualified, and do not have any member which is const-qualified,
(if they are struct or unions).
That's it. These rules should cover everything. There is no need to mention
anything about lvalues anywhere else, except to state that an lvalue (or
perhaps a modifiable one) is required.
And note how it is not necessary to inherit the lvalue attribute semantically.
According to standard C, f().d cannot be an lvalue because the struct returned
by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
above rules, however, f().d is not an lvalue simply because, although it is
a member selection, the base expression f() lacks lvalue syntactic form.
(If you can determine an attribute purely from syntax, there is no need
to compute it inheritance of abstract attributes!)
Also note another subtlety in my rules. Even when x.y is an lvalue, x isn't!
x is only an expression which has the syntactic form of an lvalue. But x
is not in lvalue context (the member selection postifix operator does not
establish one). In the standard rules, x has to be an lvalue for y to be,
because y inherits that attribute from x. But x is not being assigned and its
address isn't being taken: why must it be an lvalue?
Incidentally, wow about f().a where a is an array? Here, C99 introduced a
relaxation from C90, allowing the usage. In C90, this required a diagnostic
because only an lvalue array could produce a pointer to the first element. The
C90 rule could be expressed 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 E that has type ‘‘array of type’’, AND THAT HAS LVALUE
SYNTACTIC FORM, is converted to an expression with type ‘‘pointer to
type’’ that points to the initial element of the array object to a
pointer.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-06 00:01 -0500 |
| Message-ID | <jgnmqa$8lv$1@dont-email.me> |
| In reply to | #16672 |
On 2/3/2012 17:35, Kaz Kylheku wrote:
> On 2012-02-03, lawrence.jones@siemens.com<lawrence.jones@siemens.com> wrote:
>> Keith Thompson<kst-u@mib.org> wrote:
>>>
>>> (An aside: I've complained before that the C90 and C99 standards'
>>> definitions of "lvalue" were flawed, and suggested "expression that
>>> potentially designates an object" to fix the problem. The word
>>> "potentially" is needed to ensure that *ptr is an lvalue even if
>>> ptr==NULL. I just now noticed that N1570 has this updated wording.
>>> Looks like somebody was listening. I am inordinately pleased.)
>>
>> You're welcome. :-)
>
> A very simple, define an lvalue is as an expression which satisfies these three
> conditions:
>
> - [lvalue syntactic form] An lvalue is either a certain kind of primary
> expression, (identifier or string literal) or its operator falls into a
> certain set:
> - struct/union member selection (. operator) applied to an expression which
> itself has lvalue syntactic form).
> - pointer member selection (-> operator)
> - pointer dereference or array indexing
> If E has the syntactic form of an lvalue, then so does (E) and
> denotes the same lvalue as E.
>
Huh?
'.' and '->' and '[]' have two operands. When you say "its operator,"
do you really mean when it's either the left or right operand of these?
The first point appears to be circular: An expression is an lvalue if it
is an operand to the '.' operator and that operator's operand (which
one?) is an lvalue; one operand of the '.' operator we are trying to
figure out right now whether or not it is an lvalue.
> - [lvalue context] An lvalue is the argument of certain operators in certain
> positions (those which require lvalues):
> - destination operand of assignment
> - operand of& address-of
> - operand of increment
> - ... etc
> Expressions not in these contexts are not lvalues even if they have
> lvalue syntactic form.
>
> - [lvalue type] An lvalue has object type.
>
An "lvalue," what the "lvalue" means, and what the type of the "lvalue" is:
http://en.wikipedia.org/wiki/Haddocks%27_Eyes#Naming
> Further, lvalues are then classified as modifiable if they are not array types,
> and not const-qualified, and do not have any member which is const-qualified,
> (if they are struct or unions).
>
> That's it. These rules should cover everything. There is no need to mention
> anything about lvalues anywhere else, except to state that an lvalue (or
> perhaps a modifiable one) is required.
>
What about compound literals?
> And note how it is not necessary to inherit the lvalue attribute semantically.
> According to standard C, f().d cannot be an lvalue because the struct returned
> by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
> above rules, however, f().d is not an lvalue simply because, although it is
> a member selection, the base expression f() lacks lvalue syntactic form.
> (If you can determine an attribute purely from syntax, there is no need
> to compute it inheritance of abstract attributes!)
>
If I understand the syntactic form you've given above, then given:
enum foo { bar };
'foo' is syntactically an lvalue and 'foo.blecch' is syntactically an
lvalue and 'bar' is syntactically an lvalue and 'bar.blecch' is
syntactically an lvalue?
And for the '->' operator, the '42' in '42->blecch' is syntactically an
lvalue? Its operator is '->'. Then I guess '42->blecch' is an lvalue, too.
Then to establish context:
- The 'foo' in '&foo' is contextually and syntactically an lvalue
- The 'foo.blecch' in '&foo.blecch' is contextually and syntactically an
lvalue
- The 'bar' in '&bar' is contextually and syntactically an lvalue
- The 'bar.blecch' in '&bar.blecch' is contextually and syntactically an
lvalue
- The '42->blecch' in '&42->blecch' is contextually and syntactically an
lvalue
But then when it boils down to "type," these identifiers cannot be said
to have an object type, so they are not lvalues, right? Interesting...
So what if we have:
enum foo { bar };
char foo;
Now when we are considering '&foo', it's contextually and syntactically
an lvalue, but for the type consideration, are we considering the 'enum'
type or the 'char' object?
> [...]
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-02-06 08:46 +0000 |
| Message-ID | <20120206090944.825@kylheku.com> |
| In reply to | #16739 |
On 2012-02-06, Shao Miller <sha0.miller@gmail.com> wrote:
> On 2/3/2012 17:35, Kaz Kylheku wrote:
>>
>> A very simple, define an lvalue is as an expression which satisfies these three
>> conditions:
>>
>> - [lvalue syntactic form] An lvalue is either a certain kind of primary
>> expression, (identifier or string literal) or its operator falls into a
>> certain set:
>> - struct/union member selection (. operator) applied to an expression which
>> itself has lvalue syntactic form).
>> - pointer member selection (-> operator)
>> - pointer dereference or array indexing
>> If E has the syntactic form of an lvalue, then so does (E) and
>> denotes the same lvalue as E.
>>
>
>
> Huh?
>
> '.' and '->' and '[]' have two operands. When you say "its operator,"
> do you really mean when it's either the left or right operand of these?
No, I mean the operator of the expression. Each expression has some main
operator: the thing that we would put on the left in a bracket notation
for the abstract syntax tree (Lisp style). For instance a[b+c] could have
an AST node that could be notated ([] a (+ b c)). The [] symbol is the main
operator of the expression, and not +.
> The first point appears to be circular: An expression is an lvalue if it
> is an operand to the '.' operator and that operator's operand (which
No, an expression has the syntactic form of an lvalue if it is a member
selection expression like a.b. We are concerned about a.b, not a.
> What about compound literals?
Lvalues. I've left a lot of "etc."
>> And note how it is not necessary to inherit the lvalue attribute semantically.
>> According to standard C, f().d cannot be an lvalue because the struct returned
>> by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
>> above rules, however, f().d is not an lvalue simply because, although it is
>> a member selection, the base expression f() lacks lvalue syntactic form.
>> (If you can determine an attribute purely from syntax, there is no need
>> to compute it inheritance of abstract attributes!)
>>
>
> If I understand the syntactic form you've given above, then given:
>
> enum foo { bar };
>
> 'foo' is syntactically an lvalue and 'foo.blecch' is syntactically an
foo is syntactically an lvalue (according to my proposed rules, for the benefit
of readers jumping in mid-thread, and not according to standard C) if it is a
primary expression. foo is not a primary expression in ``enum foo''. It
is an enum label, involved in a declaration.
> lvalue and 'bar' is syntactically an lvalue and 'bar.blecch' is
> syntactically an lvalue?
>
> And for the '->' operator, the '42' in '42->blecch' is syntactically an
> lvalue?
No, an integer constant isn't. It is neither the right kind of primary
expression, nor is it one of the expression kinds like dereferencing, etc.
42->blecch could be considered syntactically an lvalue because it has a
suitable kind of operator.
But then it fails on account of the expresion being nonsense and requiring a
diagnostic. (We do not have to define lvalues such that they reject this kind
of thing; that complicates the language with redundancy.)
> Then to establish context:
> - The 'foo' in '&foo' is contextually and syntactically an lvalue
It is now, but of course this foo does not refer to the enum tag foo.
> - The 'foo.blecch' in '&foo.blecch' is contextually and syntactically an
> lvalue
Clearly, and so all that remains is for foo.blecch to make sense.
> - The '42->blecch' in '&42->blecch' is contextually and syntactically an
> lvalue
As I have defined the rules, yes. If those rules are applied first, before
the translator verifies whether 42->blech makes sense, it will have to label
the 42->blech as an lvalue candidate satisfying the first two properties:
syntactic form and context. The type determination cannot be made without
resolving ->blech, and that requires a pointer to an aggregate that has a
member whose name is blech.
So at some point it will have to conclude that the expression is not well
formed and emit a diagnostic (and possibly supply a bizarre extension of
behavior that allows 42->blech, and even allows it to remain an lvalue.)
> So what if we have:
>
> enum foo { bar };
> char foo;
>
> Now when we are considering '&foo', it's contextually and syntactically
> an lvalue, but for the type consideration, are we considering the 'enum'
> type or the 'char' object?
Of course the char object. The type of the subexpression foo in the expression
&foo is char. It is a primary expression referring to the object char foo.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-06 23:17 -0500 |
| Message-ID | <jgq8jr$484$1@dont-email.me> |
| In reply to | #16741 |
On 2/6/2012 03:46, Kaz Kylheku wrote:
> On 2012-02-06, Shao Miller<sha0.miller@gmail.com> wrote:
>> On 2/3/2012 17:35, Kaz Kylheku wrote:
>>>
>>> A very simple, define an lvalue is as an expression which satisfies these three
>>> conditions:
>>>
>>> - [lvalue syntactic form] An lvalue is either a certain kind of primary
>>> expression, (identifier or string literal) or its operator falls into a
>>> certain set:
>>> - struct/union member selection (. operator) applied to an expression which
>>> itself has lvalue syntactic form).
>>> - pointer member selection (-> operator)
>>> - pointer dereference or array indexing
>>> If E has the syntactic form of an lvalue, then so does (E) and
>>> denotes the same lvalue as E.
>>>
>> Huh?
>>
>> '.' and '->' and '[]' have two operands. When you say "its operator,"
>> do you really mean when it's either the left or right operand of these?
>
> No, I mean the operator of the expression. Each expression has some main
> operator: the thing that we would put on the left in a bracket notation
> for the abstract syntax tree (Lisp style). For instance a[b+c] could have
> an AST node that could be notated ([] a (+ b c)). The [] symbol is the main
> operator of the expression, and not +.
>
Oh, oh, oh. Sorry about that. That makes much more sense! So for each
item:
foo
"bar"
s.m
sp->m
*p
a[i]
>> The first point appears to be circular: An expression is an lvalue if it
>> is an operand to the '.' operator and that operator's operand (which
>
> No, an expression has the syntactic form of an lvalue if it is a member
> selection expression like a.b. We are concerned about a.b, not a.
>
For '.', did you mean "applied" to the right-hand operand, the left-hand
operand, or both? Which one(s) had to be an lvalue? Later on you
stated a subtlety about 'x.y' and 'x' which suggests that the left-hand
side needn't be an lvalue.
>> What about compound literals?
>
> Lvalues. I've left a lot of "etc."
>
Ok.
>>> And note how it is not necessary to inherit the lvalue attribute semantically.
>>> According to standard C, f().d cannot be an lvalue because the struct returned
>>> by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
>>> above rules, however, f().d is not an lvalue simply because, although it is
>>> a member selection, the base expression f() lacks lvalue syntactic form.
>>> (If you can determine an attribute purely from syntax, there is no need
>>> to compute it inheritance of abstract attributes!)
>>>
>>
>> If I understand the syntactic form you've given above, then given:
>>
>> enum foo { bar };
>>
>> 'foo' is syntactically an lvalue and 'foo.blecch' is syntactically an
>
> foo is syntactically an lvalue (according to my proposed rules, for the benefit
> of readers jumping in mid-thread, and not according to standard C) if it is a
> primary expression. foo is not a primary expression in ``enum foo''. It
> is an enum label, involved in a declaration.
>
primary-expression:
identifier
constant
string-literal
( expression )
By syntax alone, it sure looks like a primary-expression. It seems that
you are perhaps saying that semantically it's not? Something like N1256
6.5.1p2? I'm just trying to determine at which point we deem it
!lvalue. That would be in the contextual phase, right?
>> lvalue and 'bar' is syntactically an lvalue and 'bar.blecch' is
>> syntactically an lvalue?
>>
>> And for the '->' operator, the '42' in '42->blecch' is syntactically an
>> lvalue?
>
> No, an integer constant isn't. It is neither the right kind of primary
> expression, nor is it one of the expression kinds like dereferencing, etc.
>
Thanks for clarifying. I misunderstood you to mean the operand might or
might not be an lvalue, depending on the operator; that the operator
establishes its operands' lvalue-ness.
> 42->blecch could be considered syntactically an lvalue because it has a
> suitable kind of operator.
>
> But then it fails on account of the expresion being nonsense and requiring a
> diagnostic. (We do not have to define lvalues such that they reject this kind
> of thing; that complicates the language with redundancy.)
>
Right, ok.
>> Then to establish context:
>> - The 'foo' in '&foo' is contextually and syntactically an lvalue
>
> It is now, but of course this foo does not refer to the enum tag foo.
>
>> - The 'foo.blecch' in '&foo.blecch' is contextually and syntactically an
>> lvalue
>
> Clearly, and so all that remains is for foo.blecch to make sense.
>
>> - The '42->blecch' in '&42->blecch' is contextually and syntactically an
>> lvalue
>
> As I have defined the rules, yes. If those rules are applied first, before
> the translator verifies whether 42->blech makes sense, it will have to label
> the 42->blech as an lvalue candidate satisfying the first two properties:
> syntactic form and context. The type determination cannot be made without
> resolving ->blech, and that requires a pointer to an aggregate that has a
> member whose name is blech.
>
Makes sense.
> So at some point it will have to conclude that the expression is not well
> formed and emit a diagnostic (and possibly supply a bizarre extension of
> behavior that allows 42->blech, and even allows it to remain an lvalue.)
>
That'd be an interesting extension. Heheheh. :)
>> So what if we have:
>>
>> enum foo { bar };
>> char foo;
>>
>> Now when we are considering '&foo', it's contextually and syntactically
>> an lvalue, but for the type consideration, are we considering the 'enum'
>> type or the 'char' object?
>
> Of course the char object. The type of the subexpression foo in the expression
> &foo is char. It is a primary expression referring to the object char foo.
Ok.
[toc] | [prev] | [next] | [standalone]
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2012-02-01 18:34 -0500 |
| Message-ID | <uouov8-8bs.ln1@jones.homeip.net> |
| In reply to | #16544 |
Tim Rentsch <txr@alumni.caltech.edu> wrote: > > Are N1548 and N1570 different in any way other than the > presence or absence of change bars? Yes, there were lots of changes. -- Larry Jones We seem to be out of gun powder. -- Calvin
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-03-08 10:54 -0800 |
| Message-ID | <kfnpqcmsz3o.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #16628 |
lawrence.jones@siemens.com writes: > Tim Rentsch <txr@alumni.caltech.edu> wrote: >> >> Are N1548 and N1570 different in any way other than the >> presence or absence of change bars? > > Yes, there were lots of changes. Thank you, I see that now.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-01-25 05:00 -0800 |
| Message-ID | <kfnzkdc7x87.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #13768 |
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:
> On Nov 21, 9:25 pm, Joe Wright <joewwri...@comcast.net> wrote:
>> On 11/21/2011 15:06, Stefan Ram wrote:
>>
>>
>>
>> > Newsgroups: comp.lang.java.programmer,comp.lang.c
>> > Followup-To: comp.lang.c
>>
>> > Patricia Shanahan<p...@acm.org> writes:
>> >> My main concern with C's pointers is that they were called "pointers",
>> >> not "addresses". They behave far more like assembly language addresses
>> >> than like something more abstract, whose only job is to point.
>>
>> > An important difference between address arithmetics
>> > and pointer arithmetics can be seen here:
>>
>> > #include<stdio.h>
>>
>> > int addressdiff( void const * const b, void const * const a )
>> > { return( char const * const )b -( char const * const )a; }
>>
>> > int main( void )
>> > { char address[ 2 ];
>> > int pointer[ 2 ];
>> > printf( "%d\n", addressdiff( address + 1, address ));
>> > printf( "%d\n", addressdiff( pointer + 1, pointer )); }
>>
>> > 1
>> > 4
>>
>> > Newsgroups: comp.lang.java.programmer,comp.lang.c
>> > Followup-To: comp.lang.c
>>
>> A pointer is a variable object in storage which can hold the address of
>> another object in storage. The address is a value, the pointer is an object.
>>
>> This concept is too complicated (or too simple) to some of my old friends
>> but it works for me. Keith Thompson beat me into semi-submission several
>> years ago until I got too tired to play. But here I am again.
>>
>> A pointer is an object. A function cannot return an object.
>
> surely this happens all the time
>
> struct point
> {
> int x;
> int y;
> };
>
> struct point make_point (int a, int b)
> { struct point p; p.x = a; p.y = b; return p; }
>
> isn't that returning an object? In fact doesn't this return an object?
> [snip]
It does, as 6.2.4 p8 in N1548 makes clear.
Presumably the same was true in C99, just not explained as
clearly (nor as extensively with regard to storage duration).
[toc] | [prev] | [standalone]
Page 4 of 4 — ← Prev page 1 2 3 [4]
Back to top | Article view | comp.lang.c
csiph-web