Velocity Reviews > Re: Size of an arraylist in bytes

# Re: Size of an arraylist in bytes

Kaz Kylheku
Guest
Posts: n/a

 02-06-2012
On 2012-02-06, Shao Miller <(E-Mail Removed)> wrote:
> On 2/3/2012 17:35, Kaz Kylheku wrote:
>>
>> A very simple, define an lvalue is as an expression which satisfies these three
>> conditions:
>>
>> - [lvalue syntactic form] An lvalue is either a certain kind of primary
>> expression, (identifier or string literal) or its operator falls into a
>> certain set:
>> - struct/union member selection (. operator) applied to an expression which
>> itself has lvalue syntactic form).
>> - pointer member selection (-> operator)
>> - pointer dereference or array indexing
>> If E has the syntactic form of an lvalue, then so does (E) and
>> denotes the same lvalue as E.
>>

>
>
> Huh?
>
> '.' and '->' and '[]' have two operands. When you say "its operator,"
> do you really mean when it's either the left or right operand of these?

No, I mean the operator of the expression. Each expression has some main
operator: the thing that we would put on the left in a bracket notation
for the abstract syntax tree (Lisp style). For instance a[b+c] could have
an AST node that could be notated ([] a (+ b c)). The [] symbol is the main
operator of the expression, and not +.

> The first point appears to be circular: An expression is an lvalue if it
> is an operand to the '.' operator and that operator's operand (which

No, an expression has the syntactic form of an lvalue if it is a member
selection expression like a.b. We are concerned about a.b, not a.

Lvalues. I've left a lot of "etc."

>> And note how it is not necessary to inherit the lvalue attribute semantically.
>> According to standard C, f().d cannot be an lvalue because the struct returned
>> by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
>> above rules, however, f().d is not an lvalue simply because, although it is
>> a member selection, the base expression f() lacks lvalue syntactic form.
>> (If you can determine an attribute purely from syntax, there is no need
>> to compute it inheritance of abstract attributes!)
>>

>
> If I understand the syntactic form you've given above, then given:
>
> enum foo { bar };
>
> 'foo' is syntactically an lvalue and 'foo.blecch' is syntactically an

foo is syntactically an lvalue (according to my proposed rules, for the benefit
of readers jumping in mid-thread, and not according to standard C) if it is a
primary expression. foo is not a primary expression in ``enum foo''. It
is an enum label, involved in a declaration.

> lvalue and 'bar' is syntactically an lvalue and 'bar.blecch' is
> syntactically an lvalue?
>
> And for the '->' operator, the '42' in '42->blecch' is syntactically an
> lvalue?

No, an integer constant isn't. It is neither the right kind of primary
expression, nor is it one of the expression kinds like dereferencing, etc.

42->blecch could be considered syntactically an lvalue because it has a
suitable kind of operator.

But then it fails on account of the expresion being nonsense and requiring a
diagnostic. (We do not have to define lvalues such that they reject this kind
of thing; that complicates the language with redundancy.)

> Then to establish context:
> - The 'foo' in '&foo' is contextually and syntactically an lvalue

It is now, but of course this foo does not refer to the enum tag foo.

> - The 'foo.blecch' in '&foo.blecch' is contextually and syntactically an
> lvalue

Clearly, and so all that remains is for foo.blecch to make sense.

> - The '42->blecch' in '&42->blecch' is contextually and syntactically an
> lvalue

As I have defined the rules, yes. If those rules are applied first, before
the translator verifies whether 42->blech makes sense, it will have to label
the 42->blech as an lvalue candidate satisfying the first two properties:
syntactic form and context. The type determination cannot be made without
resolving ->blech, and that requires a pointer to an aggregate that has a
member whose name is blech.

So at some point it will have to conclude that the expression is not well
formed and emit a diagnostic (and possibly supply a bizarre extension of
behavior that allows 42->blech, and even allows it to remain an lvalue.)

> So what if we have:
>
> enum foo { bar };
> char foo;
>
> Now when we are considering '&foo', it's contextually and syntactically
> an lvalue, but for the type consideration, are we considering the 'enum'
> type or the 'char' object?

Of course the char object. The type of the subexpression foo in the expression
&foo is char. It is a primary expression referring to the object char foo.

Shao Miller
Guest
Posts: n/a

 02-07-2012
On 2/6/2012 03:46, Kaz Kylheku wrote:
> On 2012-02-06, Shao Miller<(E-Mail Removed)> wrote:
>> On 2/3/2012 17:35, Kaz Kylheku wrote:
>>>
>>> A very simple, define an lvalue is as an expression which satisfies these three
>>> conditions:
>>>
>>> - [lvalue syntactic form] An lvalue is either a certain kind of primary
>>> expression, (identifier or string literal) or its operator falls into a
>>> certain set:
>>> - struct/union member selection (. operator) applied to an expression which
>>> itself has lvalue syntactic form).
>>> - pointer member selection (-> operator)
>>> - pointer dereference or array indexing
>>> If E has the syntactic form of an lvalue, then so does (E) and
>>> denotes the same lvalue as E.
>>>

>> Huh?
>>
>> '.' and '->' and '[]' have two operands. When you say "its operator,"
>> do you really mean when it's either the left or right operand of these?

>
> No, I mean the operator of the expression. Each expression has some main
> operator: the thing that we would put on the left in a bracket notation
> for the abstract syntax tree (Lisp style). For instance a[b+c] could have
> an AST node that could be notated ([] a (+ b c)). The [] symbol is the main
> operator of the expression, and not +.
>

Oh, oh, oh. Sorry about that. That makes much more sense! So for each
item:

foo
"bar"
s.m
sp->m
*p
a[i]

>> The first point appears to be circular: An expression is an lvalue if it
>> is an operand to the '.' operator and that operator's operand (which

>
> No, an expression has the syntactic form of an lvalue if it is a member
> selection expression like a.b. We are concerned about a.b, not a.
>

For '.', did you mean "applied" to the right-hand operand, the left-hand
operand, or both? Which one(s) had to be an lvalue? Later on you
stated a subtlety about 'x.y' and 'x' which suggests that the left-hand
side needn't be an lvalue.

>
> Lvalues. I've left a lot of "etc."
>

Ok.

>>> And note how it is not necessary to inherit the lvalue attribute semantically.
>>> According to standard C, f().d cannot be an lvalue because the struct returned
>>> by f() is not an lvalue, and x.y is only an lvalue if x is. According to the
>>> above rules, however, f().d is not an lvalue simply because, although it is
>>> a member selection, the base expression f() lacks lvalue syntactic form.
>>> (If you can determine an attribute purely from syntax, there is no need
>>> to compute it inheritance of abstract attributes!)
>>>

>>
>> If I understand the syntactic form you've given above, then given:
>>
>> enum foo { bar };
>>
>> 'foo' is syntactically an lvalue and 'foo.blecch' is syntactically an

>
> foo is syntactically an lvalue (according to my proposed rules, for the benefit
> of readers jumping in mid-thread, and not according to standard C) if it is a
> primary expression. foo is not a primary expression in ``enum foo''. It
> is an enum label, involved in a declaration.
>

primary-expression:
identifier
constant
string-literal
( expression )

By syntax alone, it sure looks like a primary-expression. It seems that
you are perhaps saying that semantically it's not? Something like N1256
6.5.1p2? I'm just trying to determine at which point we deem it
!lvalue. That would be in the contextual phase, right?

>> lvalue and 'bar' is syntactically an lvalue and 'bar.blecch' is
>> syntactically an lvalue?
>>
>> And for the '->' operator, the '42' in '42->blecch' is syntactically an
>> lvalue?

>
> No, an integer constant isn't. It is neither the right kind of primary
> expression, nor is it one of the expression kinds like dereferencing, etc.
>

Thanks for clarifying. I misunderstood you to mean the operand might or
might not be an lvalue, depending on the operator; that the operator
establishes its operands' lvalue-ness.

> 42->blecch could be considered syntactically an lvalue because it has a
> suitable kind of operator.
>
> But then it fails on account of the expresion being nonsense and requiring a
> diagnostic. (We do not have to define lvalues such that they reject this kind
> of thing; that complicates the language with redundancy.)
>

Right, ok.

>> Then to establish context:
>> - The 'foo' in '&foo' is contextually and syntactically an lvalue

>
> It is now, but of course this foo does not refer to the enum tag foo.
>
>> - The 'foo.blecch' in '&foo.blecch' is contextually and syntactically an
>> lvalue

>
> Clearly, and so all that remains is for foo.blecch to make sense.
>
>> - The '42->blecch' in '&42->blecch' is contextually and syntactically an
>> lvalue

>
> As I have defined the rules, yes. If those rules are applied first, before
> the translator verifies whether 42->blech makes sense, it will have to label
> the 42->blech as an lvalue candidate satisfying the first two properties:
> syntactic form and context. The type determination cannot be made without
> resolving ->blech, and that requires a pointer to an aggregate that has a
> member whose name is blech.
>

Makes sense.

> So at some point it will have to conclude that the expression is not well
> formed and emit a diagnostic (and possibly supply a bizarre extension of
> behavior that allows 42->blech, and even allows it to remain an lvalue.)
>

That'd be an interesting extension. Heheheh.

>> So what if we have:
>>
>> enum foo { bar };
>> char foo;
>>
>> Now when we are considering '&foo', it's contextually and syntactically
>> an lvalue, but for the type consideration, are we considering the 'enum'
>> type or the 'char' object?

>
> Of course the char object. The type of the subexpression foo in the expression
> &foo is char. It is a primary expression referring to the object char foo.

Ok.

Joe keane
Guest
Posts: n/a

 02-07-2012
In article <0.f36b20a7982e693e1aa8.20120205015024GMT.874nv6nj (E-Mail Removed)>,
Ben Bacarisse <(E-Mail Removed)> wrote:
>Oh! Are you saying that
>
> memset(&a, 0, sizeof a);
>
>would *not* be fine? There's certainly no character pointer in sight
>there.

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?

Shao Miller
Guest
Posts: n/a

 02-08-2012
On 2/7/2012 12:35, Joe keane wrote:
> In article<0.f36b20a7982e693e1aa8.20120205015024GMT.8 (E-Mail Removed)>,
> Ben Bacarisse<(E-Mail Removed)> wrote:
>> Oh! Are you saying that
>>
>> memset(&a, 0, sizeof a);
>>
>> would *not* be fine? There's certainly no character pointer in sight
>> there.

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

Ben Bacarisse
Guest
Posts: n/a

 02-08-2012
Shao Miller <(E-Mail Removed)> writes:

> On 2/7/2012 12:35, Joe keane wrote:
>> In article<0.f36b20a7982e693e1aa8.20120205015024GMT.8 (E-Mail Removed)>,
>> Ben Bacarisse<(E-Mail Removed)> wrote:
>>> Oh! Are you saying that
>>>
>>> memset(&a, 0, sizeof a);
>>>
>>> would *not* be fine? There's certainly no character pointer in sight
>>> there.

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

Tim Rentsch
Guest
Posts: n/a

 03-08-2012
James Kuyper <(E-Mail Removed)> 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]

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.

Tim Rentsch
Guest
Posts: n/a

 03-08-2012
Eric Sosman <(E-Mail Removed)> writes:

> On 2/4/2012 4:25 PM, Joe keane wrote:
>> In article<jgi50h\$qp\$(E-Mail Removed)>,
>> Eric Sosman<(E-Mail Removed)> 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'.

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

Tim Rentsch
Guest
Posts: n/a

 03-08-2012
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> Tim Rentsch <(E-Mail Removed)> wrote:
>>
>> Are N1548 and N1570 different in any way other than the
>> presence or absence of change bars?

>
> Yes, there were lots of changes.

Thank you, I see that now.