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 | 20 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 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2012-02-01 18:53 -0500 |
| Message-ID | <atvov8-rcs.ln1@jones.homeip.net> |
| In reply to | #16618 |
Keith Thompson <kst-u@mib.org> wrote: > Tim Rentsch <txr@alumni.caltech.edu> writes: > > > > It is. Are N1548 and N1570 different in any way other than the > > presence or absence of change bars? > > I don't know (is there a "diff" for PDF files?), but they're dated > 2010-12-02 and 2011-04-12, respectively. I presume the latter > reflects whatever changes the committee made in those 4+ months. > > N1570 has change bars marking changes relative to N1539. For the record, N1539, N1547, and N1548 have identical content but different diff marks: N1539 has none, N1547 is against N1516 (the previous draft), and N1548 is against N1256 (C99 as corrected). Likewise, N1569 and N1570 have identical content but only N1570 has diff marks. -- Larry Jones Like I'm going to get any sleep NOW. -- Calvin
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-02-01 20:06 -0800 |
| Message-ID | <lnr4ydubf5.fsf@nuthaus.mib.org> |
| In reply to | #16629 |
lawrence.jones@siemens.com writes:
> Keith Thompson <kst-u@mib.org> wrote:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> >
>> > It is. Are N1548 and N1570 different in any way other than the
>> > presence or absence of change bars?
>>
>> I don't know (is there a "diff" for PDF files?), but they're dated
>> 2010-12-02 and 2011-04-12, respectively. I presume the latter
>> reflects whatever changes the committee made in those 4+ months.
>>
>> N1570 has change bars marking changes relative to N1539.
>
> For the record, N1539, N1547, and N1548 have identical content but
> different diff marks: N1539 has none, N1547 is against N1516 (the
> previous draft), and N1548 is against N1256 (C99 as corrected).
> Likewise, N1569 and N1570 have identical content but only N1570 has diff
> marks.
N1570's diff marks are against N1539.
And you've stated previously that the released C2011 standard has no
significant changes relatve to N1569/N1570.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-01 21:40 -0500 |
| Message-ID | <jgct3h$bku$1@dont-email.me> |
| In reply to | #16618 |
On 2/1/2012 16:53, Keith Thompson wrote: > > Personally, I think it would have made more sense to say that the > prefix is an expression (lvalue or not) of struct or union type, and > that x.y, if x is not an lvalue, yields the value of the member of > the struct or union value. In other words, values can have member > values even if there's no object in sight. (Probably not the best > possible wording.) > > (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.) > Cool. :) Whether a co-incidence or not. :) 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]; -- "The stationery store has moved. Aaargh!"
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-02-02 03:45 +0000 |
| Message-ID | <jgd0s2$mj5$1@reader1.panix.com> |
| In reply to | #16631 |
>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.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-02-01 20:14 -0800 |
| Message-ID | <lnmx91ub1d.fsf@nuthaus.mib.org> |
| In reply to | #16632 |
jgk@panix.com (Joe keane) writes:
>>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.
Once you delete the extra "[", the code's behavior is undefined; this
did not change between C99 and C11.
N1570 J.2 lists instances of undefined behavior, including this:
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).
Annex J is informative, not normative, but 6.5.6p8 describes the rules
for pointer+integer addition, and it does not allow for interpreting an
array of array of int as it it were an array of int (and of course the
indexing operator is defined in terms of pointer addition).
In practice, you could get unexpected results in the presence of
optimization; the compiler may assume that j is in the range 0..4.
--
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 | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-02-01 23:14 -0500 |
| Message-ID | <jgd2jk$1v2$1@dont-email.me> |
| In reply to | #16632 |
On 2/1/2012 10:45 PM, 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.
It won't even compvile.
If you change `=0<' to `=0;' and change `[[' to `[' and
change `..' to zero or more valid statements, you'll have something
compvilable. It will, however, exhibit undefined behavior if you
execute it.
Here's the problem: The line `a[0][j] = 0;' (as amended) is
valid only when `0 <= j && j < 5'. For all other values of `j'
its behavior is undefined. Why?
`a[0]' is an array of five `int' elements. To this five-element
array we apply the `[j]' operator. In a five-element array, only the
elements [0],[1],[2],[3],[4] can be dereferenced (it is legal to form
a pointer to the non-existent element [5], but you mustn't try to
dereference that pointer). Therefore, if `j' is negative or >= 5,
the effect of the assignment is undefined.
Yes, yes, yes, we all know `a[0][5]' and `a[1][0]' are "at the
same location." Big deal: `a[0]' is still a five-element array, not
a twenty-element array. Your implementation may define the effect of
the (amended) code, but C does not.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-02 18:38 -0500 |
| Message-ID | <jgf6q0$rg2$1@dont-email.me> |
| In reply to | #16635 |
On 2/1/2012 23:14, Eric Sosman wrote:
> On 2/1/2012 10:45 PM, 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.
>
> It won't even compvile.
>
> If you change `=0<' to `=0;' and change `[[' to `[' and
> change `..' to zero or more valid statements, you'll have something
> compvilable. It will, however, exhibit undefined behavior if you
> execute it.
>
Quite trvue.
Another quirk with bounds-checking is that if you had:
int a[4][5] = { { 0 } };
int * p = (int *) a[0];
then what are the bounds of pvointer arithmetic upon 'p'? Since the
'a[0]' there eventually yields an 'int *' value, and since "A cast that
specifies no conversion has no effect on the type or value of an
expression," would the 'int[5]' bounds carry over?
If, instead, the latter line was:
int * p = *((int (*)[20]) a[0]);
would that chvange the bounds? What about with a 'void *' or 'char *'
intermediary?
Blecch.
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-02-03 16:32 +0000 |
| Message-ID | <jgh27g$q87$1@reader1.panix.com> |
| In reply to | #16635 |
In article <jgd2jk$1v2$1@dont-email.me>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
> It won't even compvile.
[yeah don't post when you're half-asleep]
How about this:
int f(int x)
{
int a[4][5];
int *p;
int *q;
p = &a[0][5];
q = &a[1][0];
if (p != q)
barf();
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-03 11:57 -0500 |
| Message-ID | <4F2C1200.9020901@verizon.net> |
| In reply to | #16662 |
On 02/03/2012 11:32 AM, Joe keane wrote:
> In article <jgd2jk$1v2$1@dont-email.me>,
> Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
>> It won't even compvile.
>
> [yeah don't post when you're half-asleep]
>
> How about this:
>
> int f(int x)
> {
> int a[4][5];
> int *p;
> int *q;
>
> p = &a[0][5];
It might seem like that code dereferences a pointer one past the end of
an array, but the standard says that the subscript operations above are
equivalent to
p = &*(*(a+0) + 5)
When the right operand of unary & is a unary * expression, neither the &
nor the * are evaluated; the result is the same as if both were removed.
As a result, the dangerous dereference is avoided, and the code is
equivalent to
p = *(a+0) + 5
The value of p points one past the end of an array. You're allowed to
create such a pointer value, compare it for relative order with other
pointers into or one past the end of the same array, and to compare it
for equality with any valid pointer of the same type, including null
pointers. The only thing you can't do with it is dereference it.
If you changed 5 to 6, then the behavior would be undefined at the point
where it evaluates *(a+0)+6.
> q = &a[1][0];
> if (p != q)
> barf();
The standard explicitly allows a pointer one past the end of an array to
compare equal to the a pointer to a different object. What it says about
how arrays are stored in memory guarantees that, in this case, they must
compare equal.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-03 20:07 -0500 |
| Message-ID | <jgi0c8$cdb$1@dont-email.me> |
| In reply to | #16663 |
On 2/3/2012 11:57, James Kuyper wrote: > > The standard explicitly allows a pointer one past the end of an array to > compare equal to the a pointer to a different object. What it says about > how arrays are stored in memory guarantees that, in this case, they must > compare equal. A sample is N1256 6.5.9p6: "Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.94)" -- "The stationery store has moved. Aaargh!"
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-02-04 22:35 +0000 |
| Message-ID | <jgkbqv$cg$1@reader1.panix.com> |
| In reply to | #16663 |
In article <4F2C1200.9020901@verizon.net>,
James Kuyper <jameskuyper@verizon.net> wrote:
>It might seem like that code dereferences a pointer one past the end of
>an array, but the standard says that the subscript operations above are
>equivalent to
How about this:
int f(int x)
{
int a[4][5];
memset((char *)&a[0][0], 0, sizeof a);
...
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-04 18:43 -0500 |
| Message-ID | <jgkfr3$1bh$1@dont-email.me> |
| In reply to | #16690 |
On 02/04/2012 05:35 PM, Joe keane wrote:
> In article <4F2C1200.9020901@verizon.net>,
> James Kuyper <jameskuyper@verizon.net> wrote:
>> It might seem like that code dereferences a pointer one past the end of
>> an array, but the standard says that the subscript operations above are
>> equivalent to
>
> How about this:
>
> int f(int x)
> {
> int a[4][5];
>
> memset((char *)&a[0][0], 0, sizeof a);
> ...
> }
That's fine, because of the special rules for pointers to character types.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-05 01:50 +0000 |
| Message-ID | <0.f36b20a7982e693e1aa8.20120205015024GMT.874nv6nj4v.fsf@bsb.me.uk> |
| In reply to | #16698 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 02/04/2012 05:35 PM, Joe keane wrote:
>> In article <4F2C1200.9020901@verizon.net>,
>> James Kuyper <jameskuyper@verizon.net> wrote:
>>> It might seem like that code dereferences a pointer one past the end of
>>> an array, but the standard says that the subscript operations above are
>>> equivalent to
>>
>> How about this:
>>
>> int f(int x)
>> {
>> int a[4][5];
>>
>> memset((char *)&a[0][0], 0, sizeof a);
>> ...
>> }
>
> That's fine, because of the special rules for pointers to character
> types.
Oh! Are you saying that
memset(&a, 0, sizeof a);
would *not* be fine? There's certainly no character pointer in sight
there.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-04 21:37 -0500 |
| Message-ID | <jgkq1t$kch$1@dont-email.me> |
| In reply to | #16702 |
On 02/04/2012 08:50 PM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>
>> On 02/04/2012 05:35 PM, Joe keane wrote:
>>> In article <4F2C1200.9020901@verizon.net>,
>>> James Kuyper <jameskuyper@verizon.net> wrote:
>>>> It might seem like that code dereferences a pointer one past the end of
>>>> an array, but the standard says that the subscript operations above are
>>>> equivalent to
>>>
>>> How about this:
>>>
>>> int f(int x)
>>> {
>>> int a[4][5];
>>>
>>> memset((char *)&a[0][0], 0, sizeof a);
>>> ...
>>> }
>>
>> That's fine, because of the special rules for pointers to character
>> types.
>
> Oh! Are you saying that
>
> memset(&a, 0, sizeof a);
>
> would *not* be fine? There's certainly no character pointer in sight
> there.
The standard says: "The memset function copies the value of c (converted
to an unsigned char) into each of the first n characters of the object
pointed to by s."
memset() does what the standard says it does, as long as there is, in
fact, a C object containing at least n bytes starting at the location
pointed at by s, without there being any undefined behavior. That's
because the standard says what memset() does; any constraints imposed by
other parts of the standard on pointer arithmetic are irrelevant.
However, while memset() need not be written in C (I'm sure many
compilers convert it to inline assembly language) the specified behavior
could be implemented in C as:
void *memset(void *s, int c, size_t n)
{
unsigned char* puc = s;
while(n--)
*puc++ = (unsigned char)c;
}
While memset() works by fiat, the C code above is equivalent to it, and
that's in part because of the special rules for pointers to character
types. There's no visible pointer to a character type in your code, but
there is the equivalent of a hidden one in memset() itself.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-05 14:48 +0000 |
| Message-ID | <0.19f83dece1e44ddf9ea9.20120205144838GMT.87y5shmj3t.fsf@bsb.me.uk> |
| In reply to | #16706 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 02/04/2012 08:50 PM, Ben Bacarisse wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>>
>>> On 02/04/2012 05:35 PM, Joe keane wrote:
>>>> In article <4F2C1200.9020901@verizon.net>,
>>>> James Kuyper <jameskuyper@verizon.net> wrote:
>>>>> It might seem like that code dereferences a pointer one past the end of
>>>>> an array, but the standard says that the subscript operations above are
>>>>> equivalent to
>>>>
>>>> How about this:
>>>>
>>>> int f(int x)
>>>> {
>>>> int a[4][5];
>>>>
>>>> memset((char *)&a[0][0], 0, sizeof a);
>>>> ...
>>>> }
>>>
>>> That's fine, because of the special rules for pointers to character
>>> types.
>>
>> Oh! Are you saying that
>>
>> memset(&a, 0, sizeof a);
>>
>> would *not* be fine? There's certainly no character pointer in sight
>> there.
>
> The standard says: "The memset function copies the value of c (converted
> to an unsigned char) into each of the first n characters of the object
> pointed to by s."
>
> memset() does what the standard says it does, as long as there is, in
> fact, a C object containing at least n bytes starting at the location
> pointed at by s, without there being any undefined behavior. That's
> because the standard says what memset() does; any constraints imposed by
> other parts of the standard on pointer arithmetic are irrelevant.
>
> However, while memset() need not be written in C (I'm sure many
> compilers convert it to inline assembly language) the specified behavior
> could be implemented in C as:
>
> void *memset(void *s, int c, size_t n)
> {
> unsigned char* puc = s;
> while(n--)
> *puc++ = (unsigned char)c;
> }
>
> While memset() works by fiat, the C code above is equivalent to it, and
> that's in part because of the special rules for pointers to character
> types. There's no visible pointer to a character type in your code, but
> there is the equivalent of a hidden one in memset() itself.
So your comment about "the special rules for pointers to character
types" did not refer to the explicit (char *) in the code you were
commenting on, but to a hypothetical pointer in an imagined
implementation?
If I've got that right, what are the special rules that mean that a
pointer to a character type won't be subject to UB when accessing beyond
the bounds of an object?
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-05 10:20 -0500 |
| Message-ID | <jgm6n5$a0e$1@dont-email.me> |
| In reply to | #16722 |
On 02/05/2012 09:48 AM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>
>> On 02/04/2012 08:50 PM, Ben Bacarisse wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>
>>>> On 02/04/2012 05:35 PM, Joe keane wrote:
...
>>>>> int f(int x)
>>>>> {
>>>>> int a[4][5];
>>>>>
>>>>> memset((char *)&a[0][0], 0, sizeof a);
>>>>> ...
>>>>> }
>>>>
>>>> That's fine, because of the special rules for pointers to character
>>>> types.
>>>
>>> Oh! Are you saying that
>>>
>>> memset(&a, 0, sizeof a);
>>>
>>> would *not* be fine? There's certainly no character pointer in sight
>>> there.
>>
>> The standard says: "The memset function copies the value of c (converted
>> to an unsigned char) into each of the first n characters of the object
>> pointed to by s."
>>
>> memset() does what the standard says it does, as long as there is, in
>> fact, a C object containing at least n bytes starting at the location
>> pointed at by s, without there being any undefined behavior. That's
>> because the standard says what memset() does; any constraints imposed by
>> other parts of the standard on pointer arithmetic are irrelevant.
>>
>> However, while memset() need not be written in C (I'm sure many
>> compilers convert it to inline assembly language) the specified behavior
>> could be implemented in C as:
>>
>> void *memset(void *s, int c, size_t n)
>> {
>> unsigned char* puc = s;
>> while(n--)
>> *puc++ = (unsigned char)c;
>> }
>>
>> While memset() works by fiat, the C code above is equivalent to it, and
>> that's in part because of the special rules for pointers to character
>> types. There's no visible pointer to a character type in your code, but
>> there is the equivalent of a hidden one in memset() itself.
>
> So your comment about "the special rules for pointers to character
> types" did not refer to the explicit (char *) in the code you were
> commenting on,
Correct, because that char* gets converted to a void* before anything
else can be done to it, In particular, any pointer arithmetic involving
that pointer occurs inside of memset(), there's no grounds for ANY
application of 6.5.6 in the call to memset() itself, because that call
doesn't involve any pointer arithmetic.
> ... but to a hypothetical pointer in an imagined
> implementation?
>
> If I've got that right, what are the special rules that mean that a
> pointer to a character type won't be subject to UB when accessing beyond
> the bounds of an object?
None. I didn't claim that there were. What I was claiming is that a
two-dimensional array, in addition to being made up of objects (the rows
of the array) which are themselves made up of objects (the individual
elements of each row), is itself a single object, and the standard makes
it clear that pointers to character types can be used to access the
entire object. A pointer to int initialized from a[1] cannot be offset
by more than 5, or by a negative amount, nor can it be dereferenced when
offset by exactly 5, even though a naive interpretation of pointer
arithmetic would imply that other offsets could be given a meaning as
referring to elements of other rows in the same array. However, that
same pointer, converted to a character type, must be usable to access
every byte of the entire multidimensional array.
The relevant clause is 6.3.2.3p7:
> When a pointer to an object is converted to a pointer to a character type,
> the result points to the lowest addressed byte of the object. Successive increments of the
> result, up to the size of the object, yield pointers to the remaining bytes of the object.
It doesn't matter whether the object contains sub-objects; such a
pointer can still be incremented, with defined behavior - namely, that
they yield pointers to the remaining bytes of the entire object,
including all of its sub-objects.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-05 16:25 +0000 |
| Message-ID | <0.f9bce4b3c54eb6738c14.20120205162521GMT.874nv59rim.fsf@bsb.me.uk> |
| In reply to | #16724 |
James Kuyper <jameskuyper@verizon.net> writes: <snip> context: int a[4][5]; > None. I didn't claim that there were. What I was claiming is that a > two-dimensional array, in addition to being made up of objects (the rows > of the array) which are themselves made up of objects (the individual > elements of each row), is itself a single object, and the standard makes > it clear that pointers to character types can be used to access the > entire object. A pointer to int initialized from a[1] cannot be offset > by more than 5, or by a negative amount, nor can it be dereferenced when > offset by exactly 5, even though a naive interpretation of pointer > arithmetic would imply that other offsets could be given a meaning as > referring to elements of other rows in the same array. However, that > same pointer, converted to a character type, must be usable to access > every byte of the entire multidimensional array. Your justification for this is: > The relevant clause is 6.3.2.3p7: >| When a pointer to an object is converted to a pointer to a character >| type, the result points to the lowest addressed byte of the >| object. Successive increments of the result, up to the size of the >| object, yield pointers to the remaining bytes of the object. > It doesn't matter whether the object contains sub-objects; such a > pointer can still be incremented, with defined behavior - namely, that > they yield pointers to the remaining bytes of the entire object, > including all of its sub-objects. Yes, but you seem to be saying that it can be used to access all of the containing object as well. I don't see any support for that in your quote from the standard. You say a[1], converted int * is bounded to include only a[1][0] to a[1][4] but when converted to a char * it can access all of a. Apart from the fact that I don't see why "the object" in 6.3.2.3p7 must refer to the containing object of pointer after conversion to a char *, it would mean that 2D char arrays could not be bounds checked. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-02-05 12:06 -0500 |
| Message-ID | <jgmcud$dap$1@dont-email.me> |
| In reply to | #16725 |
On 02/05/2012 11:25 AM, Ben Bacarisse wrote: > James Kuyper <jameskuyper@verizon.net> writes: > <snip> > context: int a[4][5]; > >> None. I didn't claim that there were. What I was claiming is that a >> two-dimensional array, in addition to being made up of objects (the rows >> of the array) which are themselves made up of objects (the individual >> elements of each row), is itself a single object, and the standard makes >> it clear that pointers to character types can be used to access the >> entire object. A pointer to int initialized from a[1] cannot be offset >> by more than 5, or by a negative amount, nor can it be dereferenced when >> offset by exactly 5, even though a naive interpretation of pointer >> arithmetic would imply that other offsets could be given a meaning as >> referring to elements of other rows in the same array. However, that >> same pointer, converted to a character type, must be usable to access >> every byte of the entire multidimensional array. > > Your justification for this is: > >> The relevant clause is 6.3.2.3p7: >> | When a pointer to an object is converted to a pointer to a character >> | type, the result points to the lowest addressed byte of the >> | object. Successive increments of the result, up to the size of the >> | object, yield pointers to the remaining bytes of the object. > >> It doesn't matter whether the object contains sub-objects; such a >> pointer can still be incremented, with defined behavior - namely, that >> they yield pointers to the remaining bytes of the entire object, >> including all of its sub-objects. > > Yes, but you seem to be saying that it can be used to access all of the > containing object as well. A pointer to a character type can be used to access the entirety of any object that it points at the first byte of, whether that object is a, a[0], or a[0][0], or *(char*)a. > I don't see any support for that in your > quote from the standard. ... It's hard to point to the place in that clause where the standard fails to distinguish between containing objects and contained objects; if you don't see its absence, all I can do is ask you to take my word for it that it isn't there. > ... You say a[1], converted int * is bounded to > include only a[1][0] to a[1][4] but when converted to a char * it can > access all of a. Apart from the fact that I don't see why "the object" > in 6.3.2.3p7 must refer to the containing object of pointer after > conversion to a char *, it would mean that 2D char arrays could not be > bounds checked. Not quite. Given char twod[4][5]; The pointers &twod, twod, and twod[0] all have the same bounds that a implementation can check, if it chooses: &twod and &twod+1. However, in higher dimensions more limited bounds are possible. For instance, given char threed[3][4][5]; char (*p)[5] = threed[1]; You can add any value from 0 to 4 to p, though *(p+4) has undefined behavior. Therefore, threed[0] can have bounds that are narrower than the ones that apply to &threed and threed[0][0]. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-02-05 19:21 +0000 |
| Message-ID | <0.a04a0ed9784abc167035.20120205192102GMT.87y5sh84td.fsf@bsb.me.uk> |
| In reply to | #16726 |
James Kuyper <jameskuyper@verizon.net> writes: > On 02/05/2012 11:25 AM, Ben Bacarisse wrote: >> James Kuyper <jameskuyper@verizon.net> writes: >> <snip> >> context: int a[4][5]; >> >>> None. I didn't claim that there were. What I was claiming is that a >>> two-dimensional array, in addition to being made up of objects (the rows >>> of the array) which are themselves made up of objects (the individual >>> elements of each row), is itself a single object, and the standard makes >>> it clear that pointers to character types can be used to access the >>> entire object. A pointer to int initialized from a[1] cannot be offset >>> by more than 5, or by a negative amount, nor can it be dereferenced when >>> offset by exactly 5, even though a naive interpretation of pointer >>> arithmetic would imply that other offsets could be given a meaning as >>> referring to elements of other rows in the same array. However, that >>> same pointer, converted to a character type, must be usable to access >>> every byte of the entire multidimensional array. >> >> Your justification for this is: >> >>> The relevant clause is 6.3.2.3p7: >>> | When a pointer to an object is converted to a pointer to a character >>> | type, the result points to the lowest addressed byte of the >>> | object. Successive increments of the result, up to the size of the >>> | object, yield pointers to the remaining bytes of the object. >> >>> It doesn't matter whether the object contains sub-objects; such a >>> pointer can still be incremented, with defined behavior - namely, that >>> they yield pointers to the remaining bytes of the entire object, >>> including all of its sub-objects. >> >> Yes, but you seem to be saying that it can be used to access all of the >> containing object as well. > > A pointer to a character type can be used to access the entirety of any > object that it points at the first byte of, whether that object is a, > a[0], or a[0][0], or *(char*)a. Your example was about a[1]. The difference really matters to the point I am making. >> I don't see any support for that in your >> quote from the standard. ... > It's hard to point to the place in that clause where the standard fails > to distinguish between containing objects and contained objects; if you > don't see its absence, all I can do is ask you to take my word for it > that it isn't there. Really? That's what you think I was asking? You said that (char *)a[1] "must be usable to access every byte of the entire multidimensional array". The quote is about "successive increments" being used to access all of some object. How can all of the array a be accessed via successive increments of (char *)a[1]? I don't think it can. If that pointer can be used at access all of a, then it is not as a result of the paragraph you quoted. <snip> I'm going to leave the rest because the above is the crux of the matter. How all this applies to char arrays only matters once the above point is settled. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2012-02-05 15:29 -0500 |
| Message-ID | <jgmoq4$olv$1@dont-email.me> |
| In reply to | #16726 |
On 2/5/2012 12:06, James Kuyper wrote: > On 02/05/2012 11:25 AM, Ben Bacarisse wrote: >> James Kuyper<jameskuyper@verizon.net> writes: >> <snip> >> context: int a[4][5]; >> >>> None. I didn't claim that there were. What I was claiming is that a >>> two-dimensional array, in addition to being made up of objects (the rows >>> of the array) which are themselves made up of objects (the individual >>> elements of each row), is itself a single object, and the standard makes >>> it clear that pointers to character types can be used to access the >>> entire object. A pointer to int initialized from a[1] cannot be offset >>> by more than 5, or by a negative amount, nor can it be dereferenced when >>> offset by exactly 5, even though a naive interpretation of pointer >>> arithmetic would imply that other offsets could be given a meaning as >>> referring to elements of other rows in the same array. However, that >>> same pointer, converted to a character type, must be usable to access >>> every byte of the entire multidimensional array. >> >> Your justification for this is: >> >>> The relevant clause is 6.3.2.3p7: >>> | When a pointer to an object is converted to a pointer to a character >>> | type, the result points to the lowest addressed byte of the >>> | object. Successive increments of the result, up to the size of the >>> | object, yield pointers to the remaining bytes of the object. >> >>> It doesn't matter whether the object contains sub-objects; such a >>> pointer can still be incremented, with defined behavior - namely, that >>> they yield pointers to the remaining bytes of the entire object, >>> including all of its sub-objects. >> >> Yes, but you seem to be saying that it can be used to access all of the >> containing object as well. > > A pointer to a character type can be used to access the entirety of any > object that it points at the first byte of, whether that object is a, > a[0], or a[0][0], or *(char*)a. > >> I don't see any support for that in your >> quote from the standard. ... > > It's hard to point to the place in that clause where the standard fails > to distinguish between containing objects and contained objects; if you > don't see its absence, all I can do is ask you to take my word for it > that it isn't there. > >> ... You say a[1], converted int * is bounded to >> include only a[1][0] to a[1][4] but when converted to a char * it can >> access all of a. Apart from the fact that I don't see why "the object" >> in 6.3.2.3p7 must refer to the containing object of pointer after >> conversion to a char *, it would mean that 2D char arrays could not be >> bounds checked. > > Not quite. Given > char twod[4][5]; > The pointers&twod, twod, and twod[0] all have the same bounds that a > implementation can check, if it chooses:&twod and&twod+1. I think you meant '&twod', 'twod' and --> '&twod[0]' <--. Otherwise, twod[0] : 'int[4][5]' [ 'int' ] 'int (*)[5]' [ 'int' ] 'int[5]' 'int *' The final pointer points to an element of an 'int[5]', not an element of an 'int[4][5]'. It is defined to add at most '5' to this pointer, which would land you at the same location as 'twod + 1'. But it is defined to add at most '4' to 'twod', and 'twod + 4' > 'twod + 1'; different bounds. > [...] -- "The stationery store has moved. Aaargh!"
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web