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 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#18337

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-08 10:46 -0800
Message-ID<kfny5rbrkv1.fsf@x-alumni2.alumni.caltech.edu>
In reply to#16726
James Kuyper <jameskuyper@verizon.net> writes:

> [context is converting a pointer to a character pointer]
>
> 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.  [snip]

Bad conclusion.  In fact, the Standard is non-specific about which
object is being referred to, so there is no definitive conclusion
in this regard.  Furthermore, I believe the statement above is not
consistent with other evidence about how such pointers should
behave.  So, in addition to being unsupportable, it's wrong. ;)

[toc] | [prev] | [next] | [standalone]


#16707

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-05 02:39 +0000
Message-ID<20120205033019.739@kylheku.com>
In reply to#16702
On 2012-02-05, Ben Bacarisse <ben.usenet@bsb.me.uk> 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.

Under these interpretations of the standard,

  memset(&a, 0, sizeof a);

would be fine because the whole object is being operated on. The pointer taken
is &a, and that carries bounds information which says that the pointer is good
from (char *) &a all the way to (char *) &a + sizeof a.

But then:

  memset(&a[0], 0, sizeof a);

should not be okay,  becuase the bounds of the &a[0] pointer extend from
&a[0] to (char *) &a[0] + sizeof a[0], and not all the way across a.

This kind of bounds checking could be useful in structures:

  struct foo { int name[32]; mutex_t m; }

  ...

  memset(&foo_instance, 0, sizeof foo_instance); // OK

  ...

  memset(foo_instance.name, 0, 33); // bound check diagnostic

[toc] | [prev] | [next] | [standalone]


#16723

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-05 15:17 +0000
Message-ID<0.4147843525f62d940e3f.20120205151754GMT.87sjipmhr1.fsf@bsb.me.uk>
In reply to#16707
Kaz Kylheku <kaz@kylheku.com> writes:

> On 2012-02-05, Ben Bacarisse <ben.usenet@bsb.me.uk> 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.
>
> Under these interpretations of the standard,
>
>   memset(&a, 0, sizeof a);
>
> would be fine because the whole object is being operated on. The pointer taken
> is &a, and that carries bounds information which says that the pointer is good
> from (char *) &a all the way to (char *) &a + sizeof a.

Right, but that was not my point.  I wondered what the reference to
"special rules for pointers to character types" had to do with it.

> But then:
>
>   memset(&a[0], 0, sizeof a);
>
> should not be okay,  becuase the bounds of the &a[0] pointer extend from
> &a[0] to (char *) &a[0] + sizeof a[0], and not all the way across a.

6.5.3.2 p3 states that the result of &a[0] must be "as if" we'd written
a+0.  Both a and a+0 convert to a pointer to the first element of a,
but which is, of course, an array.  If the bound of such a pointer is
just that first element, then the almost universal idiom

   int zero[10];
   memset(zero, 0, sizeof zero);

will also fail.

Of course, the rules for generating the hidden range of a pointer don't
have to be uniform, so there might be a special case for arrays with one
dimension, but that's horrid!

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#16727

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-05 12:06 -0500
Message-ID<jgmcuq$dap$2@dont-email.me>
In reply to#16723
On 02/05/2012 10:17 AM, Ben Bacarisse wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
> 
>> On 2012-02-05, Ben Bacarisse <ben.usenet@bsb.me.uk> 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.
>>
>> Under these interpretations of the standard,
>>
>>   memset(&a, 0, sizeof a);

Note that &a has the type int (*)[4][5]. It is a pointer that you can
add either 0 or 1 to, though it can only when it hasn't been
incremented. The pointers (char*)&a and (char*)(&a + 1) bound the object
'a'.

>> would be fine because the whole object is being operated on. The pointer taken
>> is &a, and that carries bounds information which says that the pointer is good
>> from (char *) &a all the way to (char *) &a + sizeof a.
> 
> Right, but that was not my point.  I wondered what the reference to
> "special rules for pointers to character types" had to do with it.
> 
>> But then:
>>
>>   memset(&a[0], 0, sizeof a);

Note that &a[0] has the type int(*)[5]. You can and any integer from 0
to 4 to that pointer, though &a[0]+4 can not be dereferenced. The
pointer expressions (char*)&a[0] and (char*)(&a[0]+4) are both
permitted, and point to the same locations as (char*)&a and (char*)(&a +
1).

Therefor, on an implementation which implements run-time bounds
checking, &a and &a[0] would both have the same exact limits on them, in
terms of actual memory locations.

>> should not be okay,  becuase the bounds of the &a[0] pointer extend from
>> &a[0] to (char *) &a[0] + sizeof a[0], and not all the way across a.

I think he's thinking about &a[0][0]. That has a type of int*, and you
can add any value from 0 to 5 to it, though &a[0][0]+5 cannot be
dereferenced. The pointer expressions (char*)&a[0][0] and
(char*)(&a[0][0] + 5) compare equal to (char*)&a[0] and
(char*)&a[0]+sizeof(a[0]).


> 6.5.3.2 p3 states that the result of &a[0] must be "as if" we'd written
> a+0.  Both a and a+0 convert to a pointer to the first element of a,
> but which is, of course, an array.  If the bound of such a pointer is
> just that first element, then the almost universal idiom
> 
>    int zero[10];
>    memset(zero, 0, sizeof zero);
> 
> will also fail.
> 
> Of course, the rules for generating the hidden range of a pointer don't
> have to be uniform, so there might be a special case for arrays with one
> dimension, but that's horrid!

Luckily, no such rules apply. Even if you called memset(&a[0][0], 0,
sizeof a), there would be no problem. memset() must, internally, do the
equivalent of converting it's void* pointer argument to unsigned char*,
and a character pointer is required to be able to access the entirety of
any object it points at, whether that object is *(char*)a, a[0][0],
a[0], or a itself. A implementation that implemented run-time bounds
checking on (char*)&a[0][0] based upon sizeof(a[0]) would therefore be
non-conforming.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#16729

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-05 15:06 -0500
Message-ID<jgmnfg$g1a$1@dont-email.me>
In reply to#16727
On 2/5/2012 12:06, James Kuyper wrote:
>
> Luckily, no such rules apply. Even if you called memset(&a[0][0], 0,
> sizeof a), there would be no problem. memset() must, internally, do the
> equivalent of converting it's void* pointer argument to unsigned char*,
> and a character pointer is required to be able to access the entirety of
> any object it points at, whether that object is *(char*)a, a[0][0],
> a[0], or a itself. A implementation that implemented run-time bounds
> checking on (char*)&a[0][0] based upon sizeof(a[0]) would therefore be
> non-conforming.

   struct s_foo {
       double d;
       char ca[1];
     };
   struct s_foo foo;
   char * ptr = foo.ca;
   /* This is defined? */
   ptr - 1;

-- 
"The stationery store has moved.  Aaargh!"

[toc] | [prev] | [next] | [standalone]


#16850

Fromjgk@panix.com (Joe keane)
Date2012-02-07 17:35 +0000
Message-ID<jgrnco$ddh$1@reader1.panix.com>
In reply to#16702
In article <0.f36b20a7982e693e1aa8.20120205015024GMT.874nv6nj4v.fsf@bsb.me.uk>,
Ben Bacarisse  <ben.usenet@bsb.me.uk> wrote:
>Oh!  Are you saying that
>
>  memset(&a, 0, sizeof a);
>
>would *not* be fine?  There's certainly no character pointer in sight
>there.

How about this:

int f(int x)
{
    int a[4][5];

    memset((char *) a, 0, sizeof a);
}

int g(int x)
{
    int a[4][5];

    memset((char *) *a, 0, sizeof a);
}

int h(int x)
{
    int a[4][5];

    memset((char *) &a[0][0], 0, sizeof a);
}

I put the cast there on purpose.  I'm not sure exactly what my point
was, but you are welcome to discuss the case without the cast.

Are any of these different in terms of working?

[toc] | [prev] | [next] | [standalone]


#16899

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-07 19:51 -0500
Message-ID<jgsgo1$cfr$1@dont-email.me>
In reply to#16850
On 2/7/2012 12:35, Joe keane wrote:
> In article<0.f36b20a7982e693e1aa8.20120205015024GMT.874nv6nj4v.fsf@bsb.me.uk>,
> Ben Bacarisse<ben.usenet@bsb.me.uk>  wrote:
>> Oh!  Are you saying that
>>
>>   memset(&a, 0, sizeof a);
>>
>> would *not* be fine?  There's certainly no character pointer in sight
>> there.
>
> How about this:
>
> int f(int x)
> {
>      int a[4][5];
>
        /* 'x' is unused */
        (void) x;

        /*
         * This is fine, assuming all-bits-zero doesn't
         * yield a trap representation for an 'int'
         */
>      memset((char *) a, 0, sizeof a);
        return 0;
> }
>
> int g(int x)
> {
>      int a[4][5];
>
        /* 'x' is unused */
        (void) x;

        /*
         * This yields undefined behaviour.  '*a' has
         * type 'int[5]' and will eventually yield an
         * 'int *' pointing into that 'int[5]' array
         * object.  'sizeof a' > 'sizeof (int[5])'
         */
>      memset((char *) *a, 0, sizeof a);
        return 0;
> }
>
> int h(int x)
> {
>      int a[4][5];
>
        /* 'x' is unused */
        (void) x;

        /*
         * This is the same as in 'g', since
         * '&a[0][0]' is identical to
         * '(& *( *(a + 0) + 0) )', which is the same
         * as '(*(a + 0) + 0)', which is the same as
         * '*a + 0', which is the same as '*a'
         */
>      memset((char *)&a[0][0], 0, sizeof a);
        return 0;
> }
>
> I put the cast there on purpose.  I'm not sure exactly what my point
> was, but you are welcome to discuss the case without the cast.
>
> Are any of these different in terms of working?

Yes (see above).

[toc] | [prev] | [next] | [standalone]


#16900

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-02-08 01:14 +0000
Message-ID<0.d259a14c84f3aa02f6ba.20120208011443GMT.87zkcuf7ng.fsf@bsb.me.uk>
In reply to#16899
Shao Miller <sha0.miller@gmail.com> writes:

> On 2/7/2012 12:35, Joe keane wrote:
>> In article<0.f36b20a7982e693e1aa8.20120205015024GMT.874nv6nj4v.fsf@bsb.me.uk>,
>> Ben Bacarisse<ben.usenet@bsb.me.uk>  wrote:
>>> Oh!  Are you saying that
>>>
>>>   memset(&a, 0, sizeof a);
>>>
>>> would *not* be fine?  There's certainly no character pointer in sight
>>> there.
>>
>> How about this:
>>
>> int f(int x)
>> {
>>      int a[4][5];
>>
>        /* 'x' is unused */
>        (void) x;
>
>        /*
>         * This is fine, assuming all-bits-zero doesn't
>         * yield a trap representation for an 'int'
>         */

6.2.6.2 p5 does not permit that.

>>      memset((char *) a, 0, sizeof a);
>        return 0;
>> }

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#16705

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-05 02:31 +0000
Message-ID<20120205031841.208@kylheku.com>
In reply to#16698
On 2012-02-04, James Kuyper <jameskuyper@verizon.net> wrote:
> 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.

Nothing in that whole section of the standard applies here (to the previous
program upthread) because the object is being accessed through lvalues which
is its declared type (both through *p and *q).

Those special rules you are appealing to for character types say nothing
about those character pointers being allowed to go out of bounds!!!

For instance

  {
    int x[2][2];
    memset(x[0], 0, 4 * sizeof(int));
  }

Here, the character pointer is derived from the address of x[0], yet it is
used to overwrite the adjacent array.

That aliasing-related section of the standard tells us we can access objects
through a character lvalue; but it does not grant that we can displace a
character pointer from one object to another.

If you believe that x[0] and x[1] are separate objects such that array
displacing cannot take place from one to the other, then to be consistent,
that belief has to extend to character-based indexing also. If x[0][3] is out
of bounds, then so is (char *)x[0][3], or (char *) x[0] + 3 * sizeof(int).

If pointers carry such strict bounds information, it will not disappear under
casting.

[toc] | [prev] | [next] | [standalone]


#16675

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-03 21:26 -0500
Message-ID<jgi50h$qp$1@dont-email.me>
In reply to#16662
On 2/3/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];
>      q =&a[1][0];
>      if (p != q)
> 	barf();
> }

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

     "Absurd!" you may cry, but bear with me a moment and consider a
superficially different scenario:

	union { char c; double d; } x;
	char *pc = &x.p;
	double *pd = &x.d;

I'm sure you'll agree that in this situation `*p = 42' and `*q = 42'
have different effects -- yet `p == (char*)q' and `q = (double*)p'
and `(void*)p == (void*)q'.  A pointer is not just an address: It
also carries information about the type of the addressed object.

     ... and nothing in the C Standard bars a pointer from carrying
information about the legitimate bounds of what it points at.  In
your code we have `p == q', but even so `p' and `q' may incorporate
bits that do not influence their comparison but do influence their
other uses: `p', for instance, can "know" that it is derived from
`a[0]', and "know" that it's pointing one past the end of that array.
Similarly, `q' could "know" that it's based on `a[1]', and as a
result behave differently.

     C implementations that support such strict bounds checking are
as rare as principled politicians, but as programming costs rise
while CPU costs fall, people will spend more of the latter to save
some of the former: Bounds checking, overflow checking, and other
kinds of trip-wires, now rare, may become commonplace.  C does not
legislate against such advances.

     Anecdote about CPU resources: At lunch this very day, a colleague
told of introducing his thirteen-year-old son to C.  He didn't want to
spend time wrestling with a full-scale installation and struggling
through the inevitable morass of version clashes, so instead he used
a prepackaged solution and an emulator. For a beginner's simple
programs, the emulator delivered compile times of one or two seconds.
"In less time than I could have installed Cygwin," he said, he was
guiding his son through experiments about struct element offsets.

     What was the emulator?  It was

     - A vanilla Linux distribution, running on

     - An 80386 emulator, written in

     - JavaScript, running in

     - A browser.

     This anecdote, I think, carries two lessons: First, that the scale
of available CPU power has become enormous (hence, the power to perform
"serious" bounds checking is available already), and second, that even
today (never mind tomorrow) it seldom makes sense to optimize.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#16676

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-03 21:31 -0500
Message-ID<jgi5b1$28o$1@dont-email.me>
In reply to#16675
On 2/3/2012 9:26 PM, Eric Sosman wrote:
>[...]
> union { char c; double d; } x;
> char *pc = &x.p;
> double *pd = &x.d;
>
> I'm sure you'll agree that in this situation `*p = 42' and `*q = 42'
> have different effects

     (Sigh.)  Make that `*pc = 42' and `*pd = 42', okay?  Chalk it
up to "editing for clarity" and overlooking a few instances ...

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#16677

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-04 06:57 -0500
Message-ID<jgj6fi$14q$1@dont-email.me>
In reply to#16675
On 02/03/2012 09:26 PM, Eric Sosman wrote:
...
>      ... and nothing in the C Standard bars a pointer from carrying
> information about the legitimate bounds of what it points at. ...
...
>      C implementations that support such strict bounds checking are
> as rare as principled politicians, ...

While run-time bounds checking is the simplest way to explain how it
could matter, there is a more subtle way that I suspect is far more
likely to come up. Given:

	int a[5][4];
	int *p = a[0];
	int *q = a[1];

The fact that it's undefined behavior to dereference p+n or q+n for n<0
or n>3 means that a compiler is free to assume that p[i] never aliases
the same int as q[j], regardless of the value of i and j. I suspect that
optimizations which take advantage of that assumption, and will
therefore cause unexpected results when that assumption is violated, are
far more likely to be an issue than implementations which support
run-time bounds checking.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#16681

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-04 18:32 +0000
Message-ID<20120204192119.182@kylheku.com>
In reply to#16677
On 2012-02-04, James Kuyper <jameskuyper@verizon.net> wrote:
> On 02/03/2012 09:26 PM, Eric Sosman wrote:
> ...
>>      ... and nothing in the C Standard bars a pointer from carrying
>> information about the legitimate bounds of what it points at. ...
> ...
>>      C implementations that support such strict bounds checking are
>> as rare as principled politicians, ...
>
> While run-time bounds checking is the simplest way to explain how it
> could matter, there is a more subtle way that I suspect is far more
> likely to come up. Given:
>
> 	int a[5][4];
> 	int *p = a[0];
> 	int *q = a[1];
>
> The fact that it's undefined behavior to dereference p+n or q+n for n<0

This is not a fact but only an opinion. It's easy to argue against this
opinion because:

- arrays are a thin abstraction that really just work with pointer
  displacement and dereferencing.
- a[0][0] and a[0][1], etc, are not separate objects. This "alternative
  array geometry" trick doesn't actually produce an out of bounds pointer.
- all the lvalues involved have the same type, int.
- all the lvalues are from pointers to correct addresses.

So, a strong checking on array subobjects, if provided by a compiler,
may just be a very useful nonconforming extension. (Even if it isn't,
that's moot, because it's a behavior that programmers will likely have
to turn off to get real code running.)

> or n>3 means that a compiler is free to assume that p[i] never aliases
> the same int as q[j], regardless of the value of i and j. I suspect that
> optimizations which take advantage of that assumption, and will
> therefore cause unexpected results when that assumption is violated, are
> far more likely to be an issue than implementations which support
> run-time bounds checking.

Given that this is in a gray are and that C programs can do stuff like that, it
would be irresponsible to have that useful optimization on by default.

I would not recompile, say, a Linux distro, with that optimization on in the
global CFLAGS that is passed to every package. :)

[toc] | [prev] | [next] | [standalone]


#16738

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-05 22:51 -0500
Message-ID<jgnin6$pdd$1@dont-email.me>
In reply to#16681
On 2/4/2012 13:32, Kaz Kylheku wrote:
> On 2012-02-04, James Kuyper<jameskuyper@verizon.net>  wrote:
>> On 02/03/2012 09:26 PM, Eric Sosman wrote:
>> ...
>>>       ... and nothing in the C Standard bars a pointer from carrying
>>> information about the legitimate bounds of what it points at. ...
>> ...
>>>       C implementations that support such strict bounds checking are
>>> as rare as principled politicians, ...
>>
>> While run-time bounds checking is the simplest way to explain how it
>> could matter, there is a more subtle way that I suspect is far more
>> likely to come up. Given:
>>
>> 	int a[5][4];
>> 	int *p = a[0];
>> 	int *q = a[1];
>>
>> The fact that it's undefined behavior to dereference p+n or q+n for n<0
>
> This is not a fact but only an opinion. It's easy to argue against this
> opinion because:
>
> - arrays are a thin abstraction that really just work with pointer
>    displacement and dereferencing.
> - a[0][0] and a[0][1], etc, are not separate objects. This "alternative
>    array geometry" trick doesn't actually produce an out of bounds pointer.
> - all the lvalues involved have the same type, int.
> - all the lvalues are from pointers to correct addresses.
>

Are you arguing against James' 'p+n' as well as his 'q+n', for 'n' < 0? 
  'p' looks like it was pointing into the first byte of a set of 
objects, but wasn't pointing _beyond_ the first byte into _any_ object.

> [...]

[toc] | [prev] | [next] | [standalone]


#16685

Fromjgk@panix.com (Joe keane)
Date2012-02-04 21:25 +0000
Message-ID<jgk7nc$bh4$1@reader1.panix.com>
In reply to#16675
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'

[toc] | [prev] | [next] | [standalone]


#16687

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-04 17:08 -0500
Message-ID<jgka9b$6nm$1@dont-email.me>
In reply to#16685
On 2/4/2012 4:25 PM, 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;;

     Undefined behavior.  From here onwards, the C Standard has
nothing to say about what the program might or might not do.

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

     No such C&V, since "it works" is among the possible undefined
behaviors.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#18338

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-03-08 10:52 -0800
Message-ID<kfnty1zrkll.fsf@x-alumni2.alumni.caltech.edu>
In reply to#16687
Eric Sosman <esosman@ieee-dot-org.invalid> writes:

> On 2/4/2012 4:25 PM, 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;;
>
>     Undefined behavior.  From here onwards, the C Standard has
> nothing to say about what the program might or might not do.
>
>>      *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'
>
>     No such C&V, since "it works" is among the possible undefined
> behaviors.

Obviously what was being asked for (although the writer may
not have been aware enough to phrase it thusly) is C&V for
why this case must be undefined behavior.  And, that would
be a useful question to answer.

[toc] | [prev] | [next] | [standalone]


#16689

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-04 17:32 -0500
Message-ID<4F2DB1F2.3@verizon.net>
In reply to#16685
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];
>     q = &a[1][0];
>     if (p != q)
> 	barf();
>     *p = 2;;
>     *q = 3;;

What's with the double semi-colons?

Because dereferencing p has undefined behavior, a conforming
implementation of C can do anything it wants with this code. However, in
particular, it need not pay any attention to the fact that p and q point
at the same location. It could therefore rearrange the order of the
previous two lines, which would produce unexpected results on the
following line:

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

It can work; but it's not required to work - which is the point.

[toc] | [prev] | [next] | [standalone]


#16704

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-05 02:19 +0000
Message-ID<20120205030849.505@kylheku.com>
In reply to#16689
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];
>>     q = &a[1][0];
>>     if (p != q)
>> 	barf();
>>     *p = 2;;
>>     *q = 3;;
>
> What's with the double semi-colons?
>
> Because dereferencing p has undefined behavior, a conforming

Says you. There isn't a very convincing case for this in the standard.

It does look as if C supports flexibility with respect to the array composition
geometry imposed on an object.

> implementation of C can do anything it wants with this code. However, in

Not if that implementation of C wants a much broader user base than
just a handful of Usenet language lawyers.

> particular, it need not pay any attention to the fact that p and q point
> at the same location. 

These pointers are to the same type, and not restrict-qualified. Moreover, the
pointer displacement of both pointers has not strayed from the boundaries of
the same object object.  

Since C99, C has had a tool by which you can request this aggressively
optimizing behavior which will break the above program: make either p, q or
both restrict-qualified.

This is why restrict exists: so that the programmer can promise that p and q
are not the same object, and optimization can proceed accordingly.

[toc] | [prev] | [next] | [standalone]


#16720

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-05 09:20 -0500
Message-ID<jgm389$mjh$1@dont-email.me>
In reply to#16704
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."

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web