Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #13739 > unrolled thread

Re: Size of an arraylist in bytes

Started byJoe Wright <joewwright@comcast.net>
First post2011-11-21 16:25 -0500
Last post2012-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.


Contents

  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 →


#16629

Fromlawrence.jones@siemens.com
Date2012-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]


#16633

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#16631

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#16632

Fromjgk@panix.com (Joe keane)
Date2012-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]


#16634

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#16635

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#16643

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#16662

Fromjgk@panix.com (Joe keane)
Date2012-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]


#16663

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#16674

FromShao Miller <sha0.miller@gmail.com>
Date2012-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]


#16690

Fromjgk@panix.com (Joe keane)
Date2012-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]


#16698

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#16702

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#16706

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#16722

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#16724

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#16725

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#16726

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#16728

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#16730

FromShao Miller <sha0.miller@gmail.com>
Date2012-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