f



Alignment of foo[1][1][1][1]

Suppose I have type 'foo' and:

   sizeof (foo) == 16
   alignof (foo) == 2

Suppose I have type 'foo[1][1][1][1]' and:

   sizeof (foo[1][1][1][1]) == 16

Can:

   alignof (foo[1][1][1][1]) == 4

?  I'd like to think not, but is it prohibited?  If I do:

   typedef foo bar[1][1][1][1];
   bar * my_bar = malloc(sizeof *bar);
   foo * my_foo = (foo *) my_bar;

certainly 'my_bar' points to an object whose alignment satisfies type 
'foo'.  But what about the other way around?

   typedef foo bar[1][1][1][1];
   foo * my_foo = malloc(sizeof *foo);
   bar * my_bar = (bar *) my_foo;

'my_foo' could point to an object aligned for '2', but if the alignment 
requirement for 'bar' is '4', then the behaviour is undefined.

With a size of '16', array elements would always satisfy both alignment 
requirements.

My guess is that no implementation does this, but again: How about 
Standard-wise?
0
sha0.miller (885)
6/30/2011 4:11:37 AM
comp.lang.c 30657 articles. 5 followers. spinoza1111 (3246) is leader. Post Follow

41 Replies
1661 Views

Similar Articles

[PageSpeed] 9

On 6/29/2011 11:11 PM, Shao Miller wrote:
> Suppose I have type 'foo' and:
>
> sizeof (foo) == 16
> alignof (foo) == 2
>
> Suppose I have type 'foo[1][1][1][1]' and:
>
> sizeof (foo[1][1][1][1]) == 16
>
> Can:
>
> alignof (foo[1][1][1][1]) == 4
>
> ? I'd like to think not, but is it prohibited? If I do:
>
> typedef foo bar[1][1][1][1];
> bar * my_bar = malloc(sizeof *bar);
> foo * my_foo = (foo *) my_bar;
>
> certainly 'my_bar' points to an object whose alignment satisfies type
> 'foo'. But what about the other way around?
>
> typedef foo bar[1][1][1][1];
> foo * my_foo = malloc(sizeof *foo);
> bar * my_bar = (bar *) my_foo;
>
> 'my_foo' could point to an object aligned for '2', but if the alignment
> requirement for 'bar' is '4', then the behaviour is undefined.
>
> With a size of '16', array elements would always satisfy both alignment
> requirements.
>
> My guess is that no implementation does this, but again: How about
> Standard-wise?

Erm, pretend I didn't use 'malloc', there.  That's besides the point.
0
sha0.miller (885)
6/30/2011 4:13:15 AM
On Jun 30, 5:11=A0am, Shao Miller <sha0.mil...@gmail.com> wrote:
> My guess is that no implementation does this,

Perhaps not for arrays of length 1, but it could be a sensible
decision to require the same alignment as an int for
char[sizeof(int)]. And on my system, the natural alignment for long
long is 8 bytes, but the compiler aligns them to 4 bytes mainly to
avoid changing the ABI. It could be a sensible future decision to keep
that alignment for long long, but align arrays of long long to 8
bytes, if the cost of the ABI change would be acceptably small for
arrays. (Not that I think that is going to happen, but still...)

> but again: How about
> Standard-wise?

I don't think the standard says anything about it, which in this case
means implementors are given the freedom to use whatever alignment
works best for them.
0
truedfx (1926)
7/1/2011 4:57:11 PM
Shao Miller <sha0.miller@gmail.com> wrote:
> Suppose I have type 'foo' and:
> 
>    sizeof (foo) == 16
>    alignof (foo) == 2
> 
> Suppose I have type 'foo[1][1][1][1]' and:
> 
>    sizeof (foo[1][1][1][1]) == 16
> 
> Can:
> 
>    alignof (foo[1][1][1][1]) == 4
> 
> ?  I'd like to think not, but is it prohibited?

I'm afraid it's hard to say.  The problem is that there are at least two
potentially different kinds of alignment requirements, which I'll call
the *necessary* alignment and the *preferred* alignment.  The necessary
alignment is the alignment required by the underlying hardware and the
implementation's code generation in order for things to work correctly. 
The preferred alignment may be stricter and is what the implementation
actually uses, typically for performance reasons.  For example, on a
typical linearly addressed machine that allows unaligned accesses, the
necessary alignment for all types is 1, but implementations almost
always use an alignment equal to the size for the fundamental data
types.

The C Standard requires that any object be usable as if it were an array
with a single element.  Thus, the necessary alignment of an array cannot
be stricter than the necessary alignment of its element type.  However,
there certainly are implementations that align arrays more strictly than
their element type for performance reasons, and I wouldn't be surprised
to find some that do the same for structure types (although I've never
encountered one).

The Standard says that _Alignof() returns the "required" alignment, but
it's not clear exactly what "required" means in this context.  Is it the
necessary alignment, the preferred alignment, or maybe even something in
between?
-- 
Larry Jones

The authorities are trying to silence any view contrary to their own!
-- Calvin
0
7/2/2011 6:56:21 PM
On Jul 2, 7:56=A0pm, lawrence.jo...@siemens.com wrote:
> The C Standard requires that any object be usable as if it were an array
> with a single element. =A0Thus, the necessary alignment of an array canno=
t
> be stricter than the necessary alignment of its element type.

In n1256, the only relevant wording regarding treating arbitrary
objects as arrays that I can find is this:

"For the purposes of these operators, a pointer to an object that is
not an element of an
 array behaves the same as a pointer to the first element of an array
of length one with the
 type of the object as its element type." (for the + - < <=3D > >=3D =3D=3D
and !=3D operators)

which does not suggest to me that objects behave as arrays of length 1
in other aspects. Am I overlooking something?
0
truedfx (1926)
7/2/2011 9:16:33 PM
Shao Miller <sha0.miller@gmail.com> writes:

> Suppose I have type 'foo' and:
>
>   sizeof (foo) == 16
>   alignof (foo) == 2
>
> Suppose I have type 'foo[1][1][1][1]' and:
>
>   sizeof (foo[1][1][1][1]) == 16
>
> Can:
>
>   alignof (foo[1][1][1][1]) == 4
>
> ?  I'd like to think not, but is it prohibited?  [snip]

No, it's conforming.  An array must be aligned at least as
strictly as its elements, but the converse doesn't hold,
even for arrays of length 1.  The alignments for types (foo)
and (foo[1]) don't have to be the same, even though in any
sane implementation they will be.
0
txr1 (1467)
7/3/2011 10:23:10 PM
lawrence.jones@siemens.com writes:

> Shao Miller <sha0.miller@gmail.com> wrote:
>> Suppose I have type 'foo' and:
>> 
>>    sizeof (foo) == 16
>>    alignof (foo) == 2
>> 
>> Suppose I have type 'foo[1][1][1][1]' and:
>> 
>>    sizeof (foo[1][1][1][1]) == 16
>> 
>> Can:
>> 
>>    alignof (foo[1][1][1][1]) == 4
>> 
>> ?  I'd like to think not, but is it prohibited?
>
> I'm afraid it's hard to say.  The problem is that there are at least two
> potentially different kinds of alignment requirements, which I'll call
> the *necessary* alignment and the *preferred* alignment.  The necessary
> alignment is the alignment required by the underlying hardware and the
> implementation's code generation in order for things to work correctly. 
> The preferred alignment may be stricter and is what the implementation
> actually uses, typically for performance reasons.  For example, on a
> typical linearly addressed machine that allows unaligned accesses, the
> necessary alignment for all types is 1, but implementations almost
> always use an alignment equal to the size for the fundamental data
> types.
>
> The C Standard requires that any object be usable as if it were an array
> with a single element.  Thus, the necessary alignment of an array cannot
> be stricter than the necessary alignment of its element type.

You mean this the other way around - the alignment of an array
type must be at least as strict as the element type, and may
in fact be more strict.  The requirement you mention is in
reference to element and array objects, not types;  it doesn't
bear on the issue of alignment of array types, because the
pointers involved always point to an element of the array in
question, ie, they are of element type, not array type [*].

[*] With the understanding that the element type may itself be
a (different) array type, but that doesn't change the point.


> However,
> there certainly are implementations that align arrays more strictly than
> their element type for performance reasons, and I wouldn't be surprised
> to find some that do the same for structure types (although I've never
> encountered one).
>
> The Standard says that _Alignof() returns the "required" alignment, but
> it's not clear exactly what "required" means in this context.  Is it the
> necessary alignment, the preferred alignment, or maybe even something in
> between?

Surely the meaning of _Alignof() is meant to coincide with what
is necessary for conversion of a pointer to the type in question.
So for example,

  char *stuff = malloc( _Alignof (T) + sizeof (T) );
  ... verify the malloc succeeded ...

  T *displaced = (T*) (stuff + _Alignof (T));

must work on a conforming implementation.  It's also possible
some lesser values would work, but _Alignof (T) must be
/guaranteed/ to work, since otherwise having _Alignof would be of
no value.

(I think it goes without saying that _Alignof also must be such
that the alignments of members if T is a struct or union type, or
elements if T is an array type, will each have their individual
requirements satisfied -- meaning they can be accessed normally
and their addresses will work when converted to their respective
types.  The alignment of a struct type must take into account the
alignments of its members, etc.)

0
txr1 (1467)
7/3/2011 10:57:00 PM
Tim Rentsch <txr@alumni.caltech.edu> wrote:
> lawrence.jones@siemens.com writes:
> > The C Standard requires that any object be usable as if it were an array
> > with a single element.  Thus, the necessary alignment of an array cannot
> > be stricter than the necessary alignment of its element type.
> 
> You mean this the other way around - the alignment of an array
> type must be at least as strict as the element type, and may
> in fact be more strict.

No, I meant exactly what I said.  You're either missing the distinction
I was trying to draw between the necessary and preferred alignments or
you're conflating them.

> The requirement you mention is in
> reference to element and array objects, not types;  it doesn't
> bear on the issue of alignment of array types, because the
> pointers involved always point to an element of the array in
> question, ie, they are of element type, not array type [*].

But a pointer to an array must compare equal to a pointer to the first
element (when converted to a common type, of course), which isn't
possible in general unless the necessary alignments are the same.  The
preferred alighments can differ as you said above.
-- 
Larry Jones

These findings suggest a logical course of action. -- Calvin
0
7/6/2011 4:06:14 AM
On 7/2/2011 17:16, Harald van Dijk wrote:
> On Jul 2, 7:56 pm, lawrence.jo...@siemens.com wrote:
>> The C Standard requires that any object be usable as if it were an array
>> with a single element.  Thus, the necessary alignment of an array cannot
>> be stricter than the necessary alignment of its element type.
>
> In n1256, the only relevant wording regarding treating arbitrary
> objects as arrays that I can find is this:
>
> "For the purposes of these operators, a pointer to an object that is
> not an element of an
>   array behaves the same as a pointer to the first element of an array
> of length one with the
>   type of the object as its element type." (for the + -<  <=>  >= ==
> and != operators)
>
> which does not suggest to me that objects behave as arrays of length 1
> in other aspects. Am I overlooking something?

Do you mean such as the cast concern of the original post?  That seems 
like a slippery slope. :S
0
sha0.miller (885)
7/6/2011 2:07:29 PM
On Jul 6, 3:07=C2=A0pm, Shao Miller <sha0.mil...@gmail.com> wrote:
> On 7/2/2011 17:16, Harald van D=C4=B3k wrote:
> > On Jul 2, 7:56 pm, lawrence.jo...@siemens.com wrote:
> >> The C Standard requires that any object be usable as if it were an arr=
ay
> >> with a single element. =C2=A0Thus, the necessary alignment of an array=
 cannot
> >> be stricter than the necessary alignment of its element type.
>
> > In n1256, the only relevant wording regarding treating arbitrary
> > objects as arrays that I can find is this:
>
> > "For the purposes of these operators, a pointer to an object that is
> > not an element of an
> > =C2=A0 array behaves the same as a pointer to the first element of an a=
rray
> > of length one with the
> > =C2=A0 type of the object as its element type." (for the + -< =C2=A0<=
=3D> =C2=A0>=3D =3D=3D
> > and !=3D operators)
>
> > which does not suggest to me that objects behave as arrays of length 1
> > in other aspects. Am I overlooking something?
>
> Do you mean such as the cast concern of the original post? =C2=A0That see=
ms
> like a slippery slope. :S

In what way? I don't see any downsides to disallowing

  int i =3D 0;
  ++(*(int(*)[1])&i)[0];

If you need an array, do this:

  int i[1] =3D { 0 };
  ++i[0];

If you don't need an array, do this:

  int i =3D 0;
  ++i;

Do you have a real example where it would be useful for you to
reinterpret a non-array as an array (beyond what the standard already
permits)?
0
truedfx (1926)
7/6/2011 3:55:56 PM
On 7/6/2011 00:06, lawrence.jones@siemens.com wrote:
> Tim Rentsch<txr@alumni.caltech.edu>  wrote:
>> lawrence.jones@siemens.com writes:
>>> The C Standard requires that any object be usable as if it were an array
>>> with a single element.  Thus, the necessary alignment of an array cannot
>>> be stricter than the necessary alignment of its element type.
>>
>> You mean this the other way around - the alignment of an array
>> type must be at least as strict as the element type, and may
>> in fact be more strict.
>
> No, I meant exactly what I said.  You're either missing the distinction
> I was trying to draw between the necessary and preferred alignments or
> you're conflating them.
>
>> The requirement you mention is in
>> reference to element and array objects, not types;  it doesn't
>> bear on the issue of alignment of array types, because the
>> pointers involved always point to an element of the array in
>> question, ie, they are of element type, not array type [*].
>
> But a pointer to an array must compare equal to a pointer to the first
> element (when converted to a common type, of course), which isn't
> possible in general unless the necessary alignments are the same.  The
> preferred alighments can differ as you said above.

If I understand you correctly, "necessary alignment" is that which is 
involved in the "correctly aligned" bit of pointer conversions and 
"preferred alignment" would be where an implementation causes

   int ia[100];

to happen to land.

Regardless of which of these '_Alignof' uses, if we have:

   /* ...foo established... */
   typedef foo a_1_1_foo[1][1];

   char * cp = malloc(sizeof (a_1_1_foo) * 10);
   /* Assume success */
   cp += _Alignof (foo);

'cp' now theoretically points to an object which could have type 'foo'. 
  But how can we say whether it points to a 'foo', a 'foo[1]', a 
'foo[1][1]', a 'foo[1][1][1]', etc.?  The "points to an object that is 
not an element of an array" doesn't really seem determinable.

   /* Correctly aligned conversion? */
   a_1_1_foo * test = (void *) cp;

Or is that "jumping too far?"

   foo * step1 = (void *) cp;

Yes, 'step1' is correctly aligned.

   foo (* step2)[1] = (void *) step1;

Yes, 'step1' didn't point to an element, so it is treated as though it 
pointed to the sole element of an array.  This urges that 'foo[1]' has 
the same alignment requirement as 'foo'.

   a_1_1_foo * step3 = (void *) step2;

Hmm...  'step2' doesn't point to an element of an array according to its 
type, but it "came from" a pointer which points to an element of an 
array object (perhaps)...  It strikes me as being similar to a 
containing 'struct' (or 'union') with a single member, where the 
alignment requirement of the 'struct' is stricter than the member.
0
sha0.miller (885)
7/6/2011 5:25:22 PM
On 7/6/2011 11:55, Harald van Dijk wrote:
> On Jul 6, 3:07 pm, Shao Miller<sha0.mil...@gmail.com>  wrote:
>> On 7/2/2011 17:16, Harald van Dijk wrote:
>>
>>> which does not suggest to me that objects behave as arrays of length 1
>>> in other aspects. Am I overlooking something?
>>
>> Do you mean such as the cast concern of the original post?  That seems
>> like a slippery slope. :S
>
> In what way? I don't see any downsides to disallowing
>
>    int i = 0;
>    ++(*(int(*)[1])&i)[0];
>
> If you need an array, do this:
>
>    int i[1] = { 0 };
>    ++i[0];
>
> If you don't need an array, do this:
>
>    int i = 0;
>    ++i;
>

Those examples cover "static" and "automatic" arrays.  What about 
"allocated" or even working within "allocated" space with manual 
alignment accounting?

> Do you have a real example where it would be useful for you to
> reinterpret a non-array as an array (beyond what the standard already
> permits)?

Actually yes, this thread was prompted by a suggestion I'd made to 
someone else in another thread.  They wanted an "opaque type" which 
would be effectively compatible (non-Standardese) with the actual type. 
  That is, to pretend that one type was two different types:

   void foo_func(foo * my_foo);
   void bar_func(bar * my_bar);

I'd suggested the arbitrary:

   typedef foo bar[1][1][1];

Now you cannot accidentally do:

   foo * some_foo_ptr = ...;
   bar_func(some_foo_ptr);

Even though internally, 'bar_func' might very well simply convert its 
parameter to a 'foo *' type.  That conversion was the original cause of 
alignment concern, here.

An advantage to such an obfuscation, in my opinion, is that there can be 
no padding concerns while copying or iterating through an array of such 
types -- sizeof (bar) == sizeof (foo); contrast with 'struct's and 
'union's (however unlikely).
0
sha0.miller (885)
7/6/2011 5:53:24 PM
On Jul 6, 6:53=A0pm, Shao Miller <sha0.mil...@gmail.com> wrote:
> Actually yes, this thread was prompted by a suggestion I'd made to
> someone else in another thread. =A0They wanted an "opaque type" which
> would be effectively compatible (non-Standardese) with the actual type.
> =A0 That is, to pretend that one type was two different types:
>
> =A0 =A0void foo_func(foo * my_foo);
> =A0 =A0void bar_func(bar * my_bar);
>
> I'd suggested the arbitrary:
>
> =A0 =A0typedef foo bar[1][1][1];

Which will be problematic if any bar parameter is to be passed by
value as a function argument. But depending on the meaning of foo/bar,
this might not matter.

> Now you cannot accidentally do:
>
> =A0 =A0foo * some_foo_ptr =3D ...;
> =A0 =A0bar_func(some_foo_ptr);

But the more common solution of a struct that you yourself mention:

  typedef struct { int data; } foo;
  typedef struct { int data; } bar;

works just as well.

> Even though internally, 'bar_func' might very well simply convert its
> parameter to a 'foo *' type. =A0That conversion was the original cause of
> alignment concern, here.

Distinct unnamed structure types with identical definition are
effectively required to have the same size, representation and
alignment.

> An advantage to such an obfuscation, in my opinion, is that there can be
> no padding concerns while copying or iterating through an array of such
> types -- sizeof (bar) =3D=3D sizeof (foo); contrast with 'struct's and
> 'union's (however unlikely).

With the structure definitions above, sizeof(foo) =3D=3D sizeof(bar). The
reasoning is simple: both are compatible with the same struct { int
data; } defined in a different translation unit.
0
truedfx (1926)
7/6/2011 6:34:00 PM
On 7/6/2011 14:34, Harald van Dijk wrote:
> On Jul 6, 6:53 pm, Shao Miller<sha0.mil...@gmail.com>  wrote:
>> Actually yes, this thread was prompted by a suggestion I'd made to
>> someone else in another thread.  They wanted an "opaque type" which
>> would be effectively compatible (non-Standardese) with the actual type.
>>    That is, to pretend that one type was two different types:
>>
>>     void foo_func(foo * my_foo);
>>     void bar_func(bar * my_bar);
>>
>> I'd suggested the arbitrary:
>>
>>     typedef foo bar[1][1][1];
>
> Which will be problematic if any bar parameter is to be passed by
> value as a function argument. But depending on the meaning of foo/bar,
> this might not matter.
>

Agreed.  And you're right, the discussion partner was interested in 
pointer parameters only.

>> Now you cannot accidentally do:
>>
>>     foo * some_foo_ptr = ...;
>>     bar_func(some_foo_ptr);
>
> But the more common solution of a struct that you yourself mention:
>
>    typedef struct { int data; } foo;
>    typedef struct { int data; } bar;
>
> works just as well.
>

'foo' and 'bar' needn't be the same size as 'int'.  Their post gave me 
the impression that they already had interface functions for pointers to 
the "inner type," so I sensed that it was "too late" for the strategy 
you show above.  So I'm assuming that there is already a library and the 
request is towards adding a newer piece.

I don't recall if the original "inner type" was a scalar, aggregate or 
union, but could try to find the thread again (it was near the original 
post of this thread, likely).

>> Even though internally, 'bar_func' might very well simply convert its
>> parameter to a 'foo *' type.  That conversion was the original cause of
>> alignment concern, here.
>
> Distinct unnamed structure types with identical definition are
> effectively required to have the same size, representation and
> alignment.
>

And the path to that conclusion (in the Standard) strikes me as being 
rather round-about, if I recall that path correctly.  Heheheh.

>> An advantage to such an obfuscation, in my opinion, is that there can be
>> no padding concerns while copying or iterating through an array of such
>> types -- sizeof (bar) == sizeof (foo); contrast with 'struct's and
>> 'union's (however unlikely).
>
> With the structure definitions above, sizeof(foo) == sizeof(bar). The
> reasoning is simple: both are compatible with the same struct { int
> data; } defined in a different translation unit.

Yeahbut what if it's too late and we want 'int' and 'foo' (following 
your example) to be similar?
0
sha0.miller (885)
7/6/2011 7:48:26 PM
In article <iv2e2k$lad$1@dont-email.me>,
Shao Miller  <sha0.miller@gmail.com> wrote:
> On 7/6/2011 14:34, Harald van Dijk wrote:
> > But the more common solution of a struct that you yourself mention:
> >
> >    typedef struct { int data; } foo;
> >    typedef struct { int data; } bar;
> >
> > works just as well.
> >
> 
> 'foo' and 'bar' needn't be the same size as 'int'.  Their post gave me 
> the impression that they already had interface functions for pointers to 
> the "inner type," so I sensed that it was "too late" for the strategy 
> you show above.  So I'm assuming that there is already a library and the 
> request is towards adding a newer piece.

No, the design of the library hasn't been fixed yet.

The problem with the above solution is not that it requires choosing a
particular representation, but that it requires _exposing_ that
representation in a public header. I'd like to avoid that as far as
possible, and that's why I like pointers to incomplete structs or,
failing that, struct wrappers for void pointers.


Lauri
0
la (473)
7/6/2011 9:46:31 PM
On Jul 6, 8:48=C2=A0pm, Shao Miller <sha0.mil...@gmail.com> wrote:
> On 7/6/2011 14:34, Harald van D=C4=B3k wrote:
> > On Jul 6, 6:53 pm, Shao Miller<sha0.mil...@gmail.com> =C2=A0wrote:
> >> Actually yes, this thread was prompted by a suggestion I'd made to
> >> someone else in another thread. =C2=A0They wanted an "opaque type" whi=
ch
> >> would be effectively compatible (non-Standardese) with the actual type=
..
> >> =C2=A0 =C2=A0That is, to pretend that one type was two different types=
:
>
> >> =C2=A0 =C2=A0 void foo_func(foo * my_foo);
> >> =C2=A0 =C2=A0 void bar_func(bar * my_bar);
>[...]
> > =C2=A0 =C2=A0typedef struct { int data; } foo;
> > =C2=A0 =C2=A0typedef struct { int data; } bar;
>[...]
> I don't recall if the original "inner type" was a scalar, aggregate or
> union, but could try to find the thread again (it was near the original
> post of this thread, likely).

<http://groups.google.com/group/comp.lang.c/browse_thread/thread/
6dc9ae4aad35bd89>

It was a struct. Not only that, but it is the simplest form of what
would be class inheritance in other languages. For that, my preference
would be

typedef struct IntDict {
  Dict base;
} IntDict;

Since the conversion only needs to go one way (except for
intdict_new), the theoretical objection of Dict and IntDict having
different sizes, representations, and/or alignments does not apply.
And for the one exception, either dict_new can be made to return a
maximally aligned pointer, or intdict_new can be the single exception
that is not implemented as a wrapper method.

> Yeahbut what if it's too late and we want 'int' and 'foo' (following
> your example) to be similar?

Then my suggestions aren't guaranteed to work. Neither is foo[1][1][1]
[1].
0
truedfx (1926)
7/6/2011 9:50:14 PM
lawrence.jones@siemens.com writes:

> Tim Rentsch <txr@alumni.caltech.edu> wrote:
>> lawrence.jones@siemens.com writes:
>> > The C Standard requires that any object be usable as if it were an array
>> > with a single element.  Thus, the necessary alignment of an array cannot
>> > be stricter than the necessary alignment of its element type.
>> 
>> You mean this the other way around - the alignment of an array
>> type must be at least as strict as the element type, and may
>> in fact be more strict.
>
> No, I meant exactly what I said.  You're either missing the distinction
> I was trying to draw between the necessary and preferred alignments or
> you're conflating them.

I didn't either miss or misunderstand the distinction between
necessary and preferred alignment, nor was I conflating them.
The statement made - "the necessary alignment of an array cannot
be stricter than the necessary alignment of its element type" -
is wrong.  The implication in the other direction holds but not
this direction.  So, for example, an implementation which has
sizeof (int) == 4 could easily have the NA for 'int' be 1, but
the NA for 'int [1]' be 4 -- this might be done, eg, to
accommodate a special format for 'int (*)[]' pointers, or to
simplify the design of a vector processing unit that works with
arrays but not individual elements.  It's easy to devise an
implementation along these lines, and have it be conforming.

Let's re-examine the first statement in the initial reasoning:

>> > The C Standard requires that any object be usable as if it
>> > were an array with a single element.

In fact the C Standard does not have such a requirement.  What it
does have is a requirement that _pointers_ to non-array objects
behave just like pointers to _elements_ that are in an array
object, and this holds only for the purposes of several operators
(those being binary +/-, the relation operators, and the equality
operators).  Importantly, an operation not covered under this
provision is conversion.  We can take the address of an array, and
converting that address to a pointer to the array's element type
must succeed;  that implies the NA of the array must be at least
as strict as the NA of its elements.  However, if we take the
address of an ordinary scalar, there is no guarantee that the
pointer-to-scalar address can be converted into a pointer-to-array
type;  the lack of guarantee for such conversions is what allows
arrays to be more strictly aligned than their elements.


>> The requirement you mention is in
>> reference to element and array objects, not types;  it doesn't
>> bear on the issue of alignment of array types, because the
>> pointers involved always point to an element of the array in
>> question, ie, they are of element type, not array type [*].
>
> But a pointer to an array must compare equal to a pointer to the first
> element (when converted to a common type, of course), which isn't
> possible in general unless the necessary alignments are the same.  
> [snip re: preferred alignments]

The relationship decribed here is correct only when dealing with
an actual array;  an object that is not an element of an array
can't have its address converted to a pointer-to-array type
without potentially crossing over into undefined behavior.

Reasoning as outlined above, the necessary guarantees here are
always possible if the NA of an array is at least as restrictive
as the NA of the array's elements.  They don't have to be equal.
0
txr1 (1467)
7/7/2011 7:21:47 AM
On 7/6/2011 17:46, Lauri Alanko wrote:
> In article<iv2e2k$lad$1@dont-email.me>,
> Shao Miller<sha0.miller@gmail.com>  wrote:
>> On 7/6/2011 14:34, Harald van Dijk wrote:
>>> But the more common solution of a struct that you yourself mention:
>>>
>>>     typedef struct { int data; } foo;
>>>     typedef struct { int data; } bar;
>>>
>>> works just as well.
>>>
>>
>> 'foo' and 'bar' needn't be the same size as 'int'.  Their post gave me
>> the impression that they already had interface functions for pointers to
>> the "inner type," so I sensed that it was "too late" for the strategy
>> you show above.  So I'm assuming that there is already a library and the
>> request is towards adding a newer piece.
>
> No, the design of the library hasn't been fixed yet.
>

D'oh!  Of course "discussion partner" == Lauri Alanko.  You always have 
interesting things to discuss. :)  Sorry about forgetting.  I have to 
start using the favourite attribute in this news-reader.

> The problem with the above solution is not that it requires choosing a
> particular representation, but that it requires _exposing_ that
> representation in a public header. I'd like to avoid that as far as
> possible, and that's why I like pointers to incomplete structs or,
> failing that, struct wrappers for void pointers.

Ah, so the array obfuscation doesn't work either, then.  You don't want 
your API users to be able to use 'sizeof' on the base type, period.

Regardless of that, the array alignment business of this thread is still 
a bit odd.
0
sha0.miller (885)
7/7/2011 1:31:38 PM
On 7/6/2011 17:50, Harald van Dijk wrote:
> On Jul 6, 8:48 pm, Shao Miller<sha0.mil...@gmail.com>  wrote:
>> On 7/6/2011 14:34, Harald van Dijk wrote:
>>> On Jul 6, 6:53 pm, Shao Miller<sha0.mil...@gmail.com>    wrote:
>>>> Actually yes, this thread was prompted by a suggestion I'd made to
>>>> someone else in another thread.  They wanted an "opaque type" which
>>>> would be effectively compatible (non-Standardese) with the actual type.
>>>>     That is, to pretend that one type was two different types:
>>
>>>>      void foo_func(foo * my_foo);
>>>>      void bar_func(bar * my_bar);
>> [...]
>>>     typedef struct { int data; } foo;
>>>     typedef struct { int data; } bar;
>> [...]
>> I don't recall if the original "inner type" was a scalar, aggregate or
>> union, but could try to find the thread again (it was near the original
>> post of this thread, likely).
>
> <http://groups.google.com/group/comp.lang.c/browse_thread/thread/
> 6dc9ae4aad35bd89>
>

Oops, yes.  That was it.  Thanks.

> It was a struct. Not only that, but it is the simplest form of what
> would be class inheritance in other languages. For that, my preference
> would be
>
> typedef struct IntDict {
>    Dict base;
> } IntDict;
>

Sure.

> Since the conversion only needs to go one way (except for
> intdict_new), the theoretical objection of Dict and IntDict having
> different sizes, representations, and/or alignments does not apply.
> And for the one exception, either dict_new can be made to return a
> maximally aligned pointer, or intdict_new can be the single exception
> that is not implemented as a wrapper method.
>

The originally specified functions do suggest that it'd be one way.  I'd 
quite forgotten that Lauri Alanko was intent on not exposing any 
structure definitions.

>> Yeahbut what if it's too late and we want 'int' and 'foo' (following
>> your example) to be similar?
>
> Then my suggestions aren't guaranteed to work. Neither is foo[1][1][1]
> [1].

Agreed!  It'd still be interesting if someone dug up some bits of 
Standard which, when put together, lead to the conclusion that an 
array's alignment requirements cannot be more strict than the base type. 
  I'm not sure we'll see that.
0
sha0.miller (885)
7/7/2011 1:43:35 PM
On 7/7/2011 03:21, Tim Rentsch wrote:
>
> I didn't either miss or misunderstand the distinction between
> necessary and preferred alignment, nor was I conflating them.
> The statement made - "the necessary alignment of an array cannot
> be stricter than the necessary alignment of its element type" -
> is wrong.  The implication in the other direction holds but not
> this direction.  So, for example, an implementation which has
> sizeof (int) == 4 could easily have the NA for 'int' be 1, but
> the NA for 'int [1]' be 4 -- this might be done, eg, to
> accommodate a special format for 'int (*)[]' pointers, or to
> simplify the design of a vector processing unit that works with
> arrays but not individual elements.  It's easy to devise an
> implementation along these lines, and have it be conforming.
>
> [...]
>
> In fact the C Standard does not have such a requirement.  What it
> does have is a requirement that _pointers_ to non-array objects
> behave just like pointers to _elements_ that are in an array
> object, and this holds only for the purposes of several operators
> (those being binary +/-, the relation operators, and the equality
> operators).  Importantly, an operation not covered under this
> provision is conversion.  We can take the address of an array, and
> converting that address to a pointer to the array's element type
> must succeed;  that implies the NA of the array must be at least
> as strict as the NA of its elements.  However, if we take the
> address of an ordinary scalar, there is no guarantee that the
> pointer-to-scalar address can be converted into a pointer-to-array
> type;  the lack of guarantee for such conversions is what allows
> arrays to be more strictly aligned than their elements.
>
> [...]
>
> The relationship decribed here is correct only when dealing with
> an actual array;  an object that is not an element of an array
> can't have its address converted to a pointer-to-array type
> without potentially crossing over into undefined behavior.
>
> Reasoning as outlined above, the necessary guarantees here are
> always possible if the NA of an array is at least as restrictive
> as the NA of the array's elements.  They don't have to be equal.

I was pondering this, just now:

   int i = 1;
   int * ip = &i;
   ++ip;

So here 'ip' behaves as if it points into (where "into" includes "one 
past") an array with one element.  But indeed I agree, that doesn't mean 
that it _is_ such an array.  An example with "allocated" storage given 
elsethread.

However, an unfortunate consequence of this "freedom" seems to be that 
it is, in general, not safe to re-interpret arrays as having different 
dimensions by using array types.  One might expect that one could:

   typedef int a_5_by_5[5][5];
   a_5_by_5 array = {0};
   typedef int a_flat_5_by_5[sizeof (a_5_by_5) / sizeof (int)];
   a_flat_5_by_5 * flat_array_ptr = (void *) &array;

But that doesn't seem to be the case. :S  Of course, using:

   int * ip = array[0];

and iteration should be fine.
0
sha0.miller (885)
7/8/2011 3:24:44 AM
On Jul 8, 4:24=A0am, Shao Miller <sha0.mil...@gmail.com> wrote:
> However, an unfortunate consequence of this "freedom" seems to be that
> it is, in general, not safe to re-interpret arrays as having different
> dimensions by using array types. =A0One might expect that one could:
>
> =A0 =A0typedef int a_5_by_5[5][5];
> =A0 =A0a_5_by_5 array =3D {0};
> =A0 =A0typedef int a_flat_5_by_5[sizeof (a_5_by_5) / sizeof (int)];
> =A0 =A0a_flat_5_by_5 * flat_array_ptr =3D (void *) &array;
>
> But that doesn't seem to be the case. :S

Right.

>=A0Of course, using:
>
> =A0 =A0int * ip =3D array[0];
>
> and iteration should be fine.

Not even that, that only allows accesses up to array[0][4]. You aren't
allowed to access an array beyond its last member, even if you know
the contents of the bytes that follow. This case is mentioned in J.2:

-- 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).
0
truedfx (1926)
7/8/2011 4:11:41 PM
On 2011-07-08, Harald van D??k <truedfx@gmail.com> wrote:
> -- 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).

The interesting thing is:

Given
	int a[4][5];
	int *p1 = &a[0][0];
	int *p2 = (int *) &a;

so far as I can tell, p1 can access 5 ints, and p2 can access 20.  We
know that the layout of a is all contiguous, and we know what its bounds
are.

-s
-- 
Copyright 2011, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
0
usenet-nospam (2309)
7/8/2011 5:21:40 PM
On Jul 8, 6:21=A0pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:
> > -- An array subscript is out of range, even if an object is apparently
> > accessible with the
> > =A0 =A0given subscript (as in the lvalue expression a[1][7] given the
> > declaration int
> > =A0 =A0a[4][5]) (6.5.6).
>
> The interesting thing is:
>
> Given
> =A0 =A0 =A0 =A0 int a[4][5];
> =A0 =A0 =A0 =A0 int *p1 =3D &a[0][0];
> =A0 =A0 =A0 =A0 int *p2 =3D (int *) &a;
>
> so far as I can tell, p1 can access 5 ints, and p2 can access 20. =A0We
> know that the layout of a is all contiguous, and we know what its bounds
> are.

Is the conversion of &a to int * is guaranteed to point to a[0][0]?
Besides, the description of the + operator doesn't talk about
contiguous memory, it talks about array subscripts. p2 + 7 is valid if
p2 points to an array of length 20. The only array of int that starts
at (int *) &a -- if the result of the conversion is defined -- is
a[0], which has a length of no more than 5.
0
truedfx (1926)
7/8/2011 6:55:03 PM
On 2011-07-08, Harald van D??k <truedfx@gmail.com> wrote:
> Is the conversion of &a to int * is guaranteed to point to a[0][0]?

Pretty sure it is.

> Besides, the description of the + operator doesn't talk about
> contiguous memory, it talks about array subscripts. p2 + 7 is valid if
> p2 points to an array of length 20. The only array of int that starts
> at (int *) &a -- if the result of the conversion is defined -- is
> a[0], which has a length of no more than 5.

Doesn't matter, so far as I can tell.  If you malloc sizeof(int)*4*5 items,
and you convert the resulting address to an array[][5], and use a[0], you
are limited to 5 items, because you are currently using an lvalue of type
array[5] of int.  What matters is the size of the object you started with,
for bounds checking, and the correctness of the accessing lvalue types,
for trap representations.  So far as I can tell, that's basically it.

-s
-- 
Copyright 2011, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
0
usenet-nospam (2309)
7/8/2011 11:02:18 PM
On Jul 9, 12:02=A0am, Seebs <usenet-nos...@seebs.net> wrote:
> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:

[       int a[4][5];
        int *p1 =3D &a[0][0];
        int *p2 =3D (int *) &a; ]

> > Is the conversion of &a to int * is guaranteed to point to a[0][0]?
>
> Pretty sure it is.

Looking deeper into it, I see a lot that isn't, strictly speaking,
guaranteed by the standard, but will work on any sane implementation.
Not even malloc is guaranteed to be useful:

  int *a =3D malloc(sizeof *a);

The result of the conversion from void * to int * is not specified as
pointing to the allocated memory, as far as I can tell. But "everybody
knows" that it does. The same cannot be said for a cast from int(*)[]
[] to int *, but it may very well be possible that it is meant to be
allowed.

> > Besides, the description of the + operator doesn't talk about
> > contiguous memory, it talks about array subscripts. p2 + 7 is valid if
> > p2 points to an array of length 20. The only array of int that starts
> > at (int *) &a -- if the result of the conversion is defined -- is
> > a[0], which has a length of no more than 5.
>
> Doesn't matter, so far as I can tell. =A0If you malloc sizeof(int)*4*5 it=
ems,

The rules concerning objects' types are different for dynamically
allocated memory, and it is unclear to me how exactly the rules are
meant to interact with arrays. But your example didn't use malloc, and
automatically allocated memory's type is fixed until the end of its
lifetime. If you declare int arr[4][5];, no matter what tricks you
use, you cannot reliably access it as an int[5][4], int[10][2], or
int[20].
0
truedfx (1926)
7/8/2011 11:41:07 PM
On 7/8/2011 12:11, Harald van Dijk wrote:
> On Jul 8, 4:24 am, Shao Miller<sha0.mil...@gmail.com>  wrote:
>
>>   Of course, using:
>>
>>     int * ip = array[0];
>>
>> and iteration should be fine.
>
> Not even that, that only allows accesses up to array[0][4]. You aren't
> allowed to access an array beyond its last member, even if you know
> the contents of the bytes that follow. This case is mentioned in J.2:
>
> -- 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).

Oops.  Right.  I ought to have typed:

   int * ip = (int *) &array;

How quickly I forget (thread "Bounds Checking as Undefined Behaviour?") 
that a contiguous region of addressable memory can have bounds != the 
absolute bounds of that addressable memory, because bounds-checking is 
argued to be akin to type-checking.  Thanks for the reminder. :)

   int array[5][5];
   char * ptr = (char *) array[0];
   ptr += sizeof array[0];
   #if 0 /* Uh oh */
   ++ptr;
   #endif
   ptr = (char *) &array;
   ptr += sizeof array[0];
   ++ptr;
0
sha0.miller (885)
7/9/2011 3:55:04 AM
Harald van Dijk <truedfx@gmail.com> writes:

> On Jul 8, 4:24 am, Shao Miller <sha0.mil...@gmail.com> wrote:
>> However, an unfortunate consequence of this "freedom" seems to be that
>> it is, in general, not safe to re-interpret arrays as having different
>> dimensions by using array types.  One might expect that one could:
>>
>>    typedef int a_5_by_5[5][5];
>>    a_5_by_5 array = {0};
>>    typedef int a_flat_5_by_5[sizeof (a_5_by_5) / sizeof (int)];
>>    a_flat_5_by_5 * flat_array_ptr = (void *) &array;
>>
>> But that doesn't seem to be the case. :S
>
> Right.
>
>> Of course, using:
>>
>>    int * ip = array[0];
>>
>> and iteration should be fine.
>
> Not even that, that only allows accesses up to array[0][4]. You aren't
> allowed to access an array beyond its last member, even if you know
> the contents of the bytes that follow.  [snip J.2 reference]

Unfortunately the Standard is woefully unclear on this issue,
not whether some UB exists around array indexing but which
cases constitute UB and which do not.  Can this conclusion
be demonstrated using only normative text and not informative
text (such as Annex J)?  I agree that a case can be made, but
can you make a case that's convincing without relying on
informative text or having to generalize from examples?
0
txr1 (1467)
7/9/2011 3:55:32 PM
On Jul 9, 4:55=A0pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> Harald van Dijk <true...@gmail.com> writes:
> > On Jul 8, 4:24 am, Shao Miller <sha0.mil...@gmail.com> wrote:
> >> However, an unfortunate consequence of this "freedom" seems to be that
> >> it is, in general, not safe to re-interpret arrays as having different
> >> dimensions by using array types. =A0One might expect that one could:
>
> >> =A0 =A0typedef int a_5_by_5[5][5];
> >> =A0 =A0a_5_by_5 array =3D {0};
> >> =A0 =A0typedef int a_flat_5_by_5[sizeof (a_5_by_5) / sizeof (int)];
> >> =A0 =A0a_flat_5_by_5 * flat_array_ptr =3D (void *) &array;
>
> >> But that doesn't seem to be the case. :S
>
> > Right.
>
> >> Of course, using:
>
> >> =A0 =A0int * ip =3D array[0];
>
> >> and iteration should be fine.
>
> > Not even that, that only allows accesses up to array[0][4]. You aren't
> > allowed to access an array beyond its last member, even if you know
> > the contents of the bytes that follow. =A0[snip J.2 reference]
>
> Unfortunately the Standard is woefully unclear on this issue,
> not whether some UB exists around array indexing but which
> cases constitute UB and which do not. =A0Can this conclusion
> be demonstrated using only normative text and not informative
> text (such as Annex J)? =A0I agree that a case can be made, but
> can you make a case that's convincing without relying on
> informative text or having to generalize from examples?

The behaviour of the + operator is only defined for those cases where
both the pointer operand and the result point into (or just past) the
same array. Since that is not the case for &array[0][0] + 7 (not for
an array of int, anyway), the behaviour is undefined by omission.

I cannot, however, show that (&array[0][0])[5] is invalid. The +
points one past array[0], but the description of the unary * operator
talks about "if [the operand] points to an object", and if you were to
claim that &array[0][0] + 5 points to &array[1][0], I couldn't explain
why that's wrong.
0
truedfx (1926)
7/9/2011 4:19:22 PM
Harald van Dijk <truedfx@gmail.com> writes:

> On Jul 8, 6:21 pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:
>> > -- 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).
>>
>> The interesting thing is:
>>
>> Given
>>         int a[4][5];
>>         int *p1 = &a[0][0];
>>         int *p2 = (int *) &a;
>>
>> so far as I can tell, p1 can access 5 ints, and p2 can access 20.  We
>> know that the layout of a is all contiguous, and we know what its bounds
>> are.
>
> Is the conversion of &a to int * is guaranteed to point to a[0][0]?

The short answer is yes.  Similar questions about pointer
conversions have been debated in comp.std.c and IIRC there were
a few holdouts for the idea that it possible (as they read the
Standard) to construct a conforming implementation where such
relationships would not hold.  However, outside the milieu of
comp.std.c, I think is it fair to say that the overwhelming
consensus is that the Standard does indeed guarantee the
aforementioned property.

> Besides, the description of the + operator doesn't talk about
> contiguous memory, it talks about array subscripts. p2 + 7 is valid if
> p2 points to an array of length 20. The only array of int that starts
> at (int *) &a -- if the result of the conversion is defined -- is
> a[0], which has a length of no more than 5.

Again we are saddled with the problem that what the Standard
requires (or is intended to require) simply isn't clear.  If
we fall back to "general understanding of the community", based
on that metric I believe the judgments would be that 'p1+7' is
not defined, 'p2+7' is defined (as is 'p2[7]'), and various
intermediate cases aren't always clear.
0
txr1 (1467)
7/9/2011 5:00:07 PM
Harald van Dijk <truedfx@gmail.com> writes:

> On Jul 9, 12:02 am, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:
>
> [       int a[4][5];
>         int *p1 = &a[0][0];
>         int *p2 = (int *) &a; ]
>
>> > Is the conversion of &a to int * is guaranteed to point to a[0][0]?
>>
>> Pretty sure it is.
>
> Looking deeper into it, I see a lot that isn't, strictly speaking,
> guaranteed by the standard, but will work on any sane implementation.
> Not even malloc is guaranteed to be useful:
>
>   int *a = malloc(sizeof *a);
>
> The result of the conversion from void * to int * is not specified as
> pointing to the allocated memory, as far as I can tell.  [snip]

Did you read 7.20.3p1?


>> > Besides, the description of the + operator doesn't talk about
>> > contiguous memory, it talks about array subscripts. p2 + 7 is valid if
>> > p2 points to an array of length 20. The only array of int that starts
>> > at (int *) &a -- if the result of the conversion is defined -- is
>> > a[0], which has a length of no more than 5.
>>
>> Doesn't matter, so far as I can tell.  If you malloc sizeof(int)*4*5 items,
>
> The rules concerning objects' types are different for dynamically
> allocated memory, and it is unclear to me how exactly the rules are
> meant to interact with arrays.

Objects don't have types.  Objects have an /effective type/ for
the purposes of a particular access, but objects do not have a
type.  If E is an lvalue such that &E is legal, we may always
construct '(unsigned char (*)[ sizeof (E) ]) &E'.  Do you agree?
And that such a pointer may be used to access any part of the
object to which the unconverted expression E refers?


> But your example didn't use malloc, and
> automatically allocated memory's type is fixed until the end of its
> lifetime. If you declare int arr[4][5];, no matter what tricks you
> use, you cannot reliably access it as an int[5][4], int[10][2], or
> int[20].

Despite how some people read the Standard, the general
understanding (including AFAIK the WG14 committee) is that
you can (assuming no alignment incompatibility issues),
using the technique of casting the address of the entire
array.
0
txr1 (1467)
7/9/2011 5:32:47 PM
Harald van Dijk <truedfx@gmail.com> writes:

> On Jul 9, 4:55 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>> Harald van Dijk <true...@gmail.com> writes:
>> > On Jul 8, 4:24 am, Shao Miller <sha0.mil...@gmail.com> wrote:
>> >> However, an unfortunate consequence of this "freedom" seems to be that
>> >> it is, in general, not safe to re-interpret arrays as having different
>> >> dimensions by using array types.  One might expect that one could:
>>
>> >>    typedef int a_5_by_5[5][5];
>> >>    a_5_by_5 array = {0};
>> >>    typedef int a_flat_5_by_5[sizeof (a_5_by_5) / sizeof (int)];
>> >>    a_flat_5_by_5 * flat_array_ptr = (void *) &array;
>>
>> >> But that doesn't seem to be the case. :S
>>
>> > Right.
>>
>> >> Of course, using:
>>
>> >>    int * ip = array[0];
>>
>> >> and iteration should be fine.
>>
>> > Not even that, that only allows accesses up to array[0][4]. You aren't
>> > allowed to access an array beyond its last member, even if you know
>> > the contents of the bytes that follow.  [snip J.2 reference]
>>
>> Unfortunately the Standard is woefully unclear on this issue,
>> not whether some UB exists around array indexing but which
>> cases constitute UB and which do not.  Can this conclusion
>> be demonstrated using only normative text and not informative
>> text (such as Annex J)?  I agree that a case can be made, but
>> can you make a case that's convincing without relying on
>> informative text or having to generalize from examples?
>
> The behaviour of the + operator is only defined for those cases where
> both the pointer operand and the result point into (or just past) the
> same array. [snip elaboration]

That's true but it begs the question because it doesn't
say _which_ array.  What "the array" is can be affected
by pointer conversion.  Consider this example:

  int i20[20];
  int (*i45)[5] = (int (*)[5]) &i20; /* assume alignment is okay */
  i45[1][7];

I claim that the last line exhibits undefined behavior.  Or do
you think the behavior here should be defined?
0
txr1 (1467)
7/9/2011 5:48:55 PM
On Jul 9, 6:32=A0pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> Harald van Dijk <true...@gmail.com> writes:
> > On Jul 9, 12:02 am, Seebs <usenet-nos...@seebs.net> wrote:
> >> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:
>
> > [ =A0 =A0 =A0 int a[4][5];
> > =A0 =A0 =A0 =A0 int *p1 =3D &a[0][0];
> > =A0 =A0 =A0 =A0 int *p2 =3D (int *) &a; ]
>
> >> > Is the conversion of &a to int * is guaranteed to point to a[0][0]?
>
> >> Pretty sure it is.
>
> > Looking deeper into it, I see a lot that isn't, strictly speaking,
> > guaranteed by the standard, but will work on any sane implementation.
> > Not even malloc is guaranteed to be useful:
>
> > =A0 int *a =3D malloc(sizeof *a);
>
> > The result of the conversion from void * to int * is not specified as
> > pointing to the allocated memory, as far as I can tell. =A0[snip]
>
> Did you read 7.20.3p1?

Thanks, I missed that. By putting it there, it only applies to (c|m|
re)alloc, as an exception to the general rules for pointer conversions
as defined in 6.3 "Conversions". It does not apply to other
conversions from void * to T *, so unless part of a T * -> void * ->
T* conversion sequence, is the behaviour of such a conversion defined?
Consider a conversion sequence T * -> void * -> char * -> void * -> T
*, which happens with a custom implementation of qsort or similar
functions.

Disclaimer: I'm not suggesting that relying on that conversion is a
bad idea. I'm saying the standard fails to state that relying on that
conversion is valid.

> >> > Besides, the description of the + operator doesn't talk about
> >> > contiguous memory, it talks about array subscripts. p2 + 7 is valid =
if
> >> > p2 points to an array of length 20. The only array of int that start=
s
> >> > at (int *) &a -- if the result of the conversion is defined -- is
> >> > a[0], which has a length of no more than 5.
>
> >> Doesn't matter, so far as I can tell. =A0If you malloc sizeof(int)*4*5=
 items,
>
> > The rules concerning objects' types are different for dynamically
> > allocated memory, and it is unclear to me how exactly the rules are
> > meant to interact with arrays.
>
> Objects don't have types. =A0Objects have an /effective type/ for
> the purposes of a particular access, but objects do not have a
> type.

Right, that was badly worded. It is the effective type that is handled
differently for dynamically allocated memory.

>=A0If E is an lvalue such that &E is legal, we may always
> construct '(unsigned char (*)[ sizeof (E) ]) &E'. =A0Do you agree?

No, but I think it's not relevant to this discussion. I agree that we
may always construct (unsigned char *) &E, and believe that serves
your point just as well.

> And that such a pointer may be used to access any part of the
> object to which the unconverted expression E refers?

Yes.

> Despite how some people read the Standard, the general
> understanding (including AFAIK the WG14 committee) is that
> you can (assuming no alignment incompatibility issues),
> using the technique of casting the address of the entire
> array.

There is a special exception for character types, but can you show the
support this for any other type?
0
truedfx (1926)
7/9/2011 8:22:19 PM
On Jul 9, 6:48=A0pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> Consider this example:
>
> =A0 int i20[20];
> =A0 int (*i45)[5] =3D (int (*)[5]) &i20; /* assume alignment is okay */
> =A0 i45[1][7];
>
> I claim that the last line exhibits undefined behavior. =A0Or do
> you think the behavior here should be defined?

I agree the behaviour is undefined, but for a different reason than
you: my point in this thread was that you cannot access an int[4][5]
as an int[20], but that works both ways: I believe you cannot access
an int[20] as an int[4][5] either.
0
truedfx (1926)
7/9/2011 8:25:25 PM
Harald van Dijk <truedfx@gmail.com> writes:

> On Jul 9, 6:48 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>> Consider this example:
>>
>>   int i20[20];
>>   int (*i45)[5] = (int (*)[5]) &i20; /* assume alignment is okay */
>>   i45[1][7];
>>
>> I claim that the last line exhibits undefined behavior.  Or do
>> you think the behavior here should be defined?
>
> I agree the behaviour is undefined, but for a different reason than
> you: my point in this thread was that you cannot access an int[4][5]
> as an int[20], but that works both ways: I believe you cannot access
> an int[20] as an int[4][5] either.

My apologies for a very delayed response.

I find your statement mildly astonishing.  What section(s) of
the Standard do you believe such an access would violate
(assuming as usual no alignment problems on the pointer
conversion)?
0
txr1 (1467)
9/4/2011 6:00:52 PM
Harald van Dijk <truedfx@gmail.com> writes:

[again my apologies for a much delayed response]

> On Jul 9, 6:32 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>> Harald van Dijk <true...@gmail.com> writes:
>> > On Jul 9, 12:02 am, Seebs <usenet-nos...@seebs.net> wrote:
>> >> On 2011-07-08, Harald van D??k <true...@gmail.com> wrote:
>>
>> > [       int a[4][5];
>> >         int *p1 = &a[0][0];
>> >         int *p2 = (int *) &a; ]
>>
>> >> > Is the conversion of &a to int * is guaranteed to point to a[0][0]?
>>
>> >> Pretty sure it is.
>>
>> > Looking deeper into it, I see a lot that isn't, strictly speaking,
>> > guaranteed by the standard, but will work on any sane implementation.
>> > Not even malloc is guaranteed to be useful:
>>
>> >   int *a = malloc(sizeof *a);
>>
>> > The result of the conversion from void * to int * is not specified as
>> > pointing to the allocated memory, as far as I can tell.  [snip]
>>
>> Did you read 7.20.3p1?
>
> Thanks, I missed that. By putting it there, it only applies to (c|m|
> re)alloc, as an exception to the general rules for pointer conversions
> as defined in 6.3 "Conversions". It does not apply to other
> conversions from void * to T *, so unless part of a T * -> void * ->
> T* conversion sequence, is the behaviour of such a conversion defined?

I believe it is, yes.

> Consider a conversion sequence T * -> void * -> char * -> void * -> T
> *, which happens with a custom implementation of qsort or similar
> functions.

That particular conversion sequence actually is guaranteed fairly
directly by 6.3.2.3.  But I assume you mean to ask a more subtle
question.

> Disclaimer: I'm not suggesting that relying on that conversion is a
> bad idea. I'm saying the standard fails to state that relying on that
> conversion is valid.

It doesn't say it as directly as some people would like.  Different
people make different assumptions about how the Standard should be
interpreted.  My best understanding is, reading the Standard as WG14
intends or expects it to be interpreted, the Standard actually does
guarantee that pointer conversions work the way most (informed)
people expect them to work.  (More details below...)


>> >> > Besides, the description of the + operator doesn't talk about
>> >> > contiguous memory, it talks about array subscripts. p2 + 7 is valid if
>> >> > p2 points to an array of length 20. The only array of int that starts
>> >> > at (int *) &a -- if the result of the conversion is defined -- is
>> >> > a[0], which has a length of no more than 5.
>>
>> >> Doesn't matter, so far as I can tell.  If you malloc sizeof(int)*4*5 items,
>>
>> > The rules concerning objects' types are different for dynamically
>> > allocated memory, and it is unclear to me how exactly the rules are
>> > meant to interact with arrays.
>>
>> Objects don't have types.  Objects have an /effective type/ for
>> the purposes of a particular access, but objects do not have a
>> type.
>
> Right, that was badly worded. It is the effective type that is handled
> differently for dynamically allocated memory.

The notion of effective type is irrelevant to these questions
about pointer conversion and array indexing.  By the time an
access happens, all the pointer conversion and indexing
arithmetic has been done;  as long as the ultimate element
type matches, if the conversions and indexings worked then
the access works -- and effective type doesn't enter into
the stipulations for pointer conversions or array indexing.


>> If E is an lvalue such that &E is legal, we may always
>> construct '(unsigned char (*)[ sizeof (E) ]) &E'.  Do you agree?
>
> No, but I think it's not relevant to this discussion.

Right, I should have mentioned the condition about alignment,
which was meant to be implied.

> I agree that we
> may always construct (unsigned char *) &E, and believe that serves
> your point just as well.

Probably you're right;  I thought putting in the size
explicitly made the point more clearly.


>> And that such a pointer may be used to access any part of the
>> object to which the unconverted expression E refers?
>
> Yes.
>
>> Despite how some people read the Standard, the general
>> understanding (including AFAIK the WG14 committee) is that
>> you can (assuming no alignment incompatibility issues),
>> using the technique of casting the address of the entire
>> array.
>
> There is a special exception for character types, but can you show the
> support this for any other type?

I will ask a question:  do you believe the Standard defines
"pointers" or "pointer values" in such a way that valid pointers
(that aren't null) point to some object?  I believe it does -
pointers (even pointers of type (void*)) don't point "nowhere", they
point at something (as before assuming they aren't null or don't
have alignment problems).  The behavior of various pointer
conversions follows from this implication.

I know some people read some sections of 6.3.2.3 (notably, for
example, the third sentence of 6.3.2.3p7) as limiting how pointer
conversions work.  IMO that interpretation is incorrect;  these
sentences are meant to add to what is allowed for pointer
conversions, not take away from them.  For example, consider this
fragment:

  int  *p0 = malloc( sizeof *p0 );
  long *p1 = (long*) p0;    
  int  *p2 = (int*) p1;
  //  now p2 == p0 must be true, even if sizeof (long) > sizeof (int)

We know all these conversions are legal just by the first sentence
of 6.3.2.3p7 (as usual assuming no alignment problems (if indeed
any assumption is actually needed, because of calling malloc())).
However, there is some question about what the conversions do,
because the object actually allocated may not be large enough to
accommodate a (long) object.  The third sentence of 6.3.2.3p7
means the conversions have to work the way we expect even in this
case, where the object size actually available isn't large enough
for the pointer type in question.  When the object size /is/ large
enough for the converted-to pointer type, then the pointer also
has to work for purposes of dererencing (again assuming no
alignment issues, and no violations of effective type rules).
This conclusion follows from the principle that any valid pointer
value (that isn't null) points to some object.

I agree that the Standard doesn't say all this as clearly or as
directly as I would like.  But I believe it is the most consistent
reading of what the Standard does say, and also is how WG14
intends and expects the Standard will be interpreted.  I don't
have any specific examples to cite in support of this last part;
as often happens with deeply held assumptions, it comes out more
as a general sense from the writing (including the Standard, DR's,
and the Rationale document primarily) than from any specific
statement or set of statements.
0
txr1 (1467)
9/4/2011 7:23:26 PM
On Sep 4, 8:00=A0pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> Harald van Dijk <true...@gmail.com> writes:
> > On Jul 9, 6:48 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> >> Consider this example:
>
> >> =A0 int i20[20];
> >> =A0 int (*i45)[5] =3D (int (*)[5]) &i20; /* assume alignment is okay *=
/
> >> =A0 i45[1][7];
>
> >> I claim that the last line exhibits undefined behavior. =A0Or do
> >> you think the behavior here should be defined?
>
> > I agree the behaviour is undefined, but for a different reason than
> > you: my point in this thread was that you cannot access an int[4][5]
> > as an int[20], but that works both ways: I believe you cannot access
> > an int[20] as an int[4][5] either.
>
> My apologies for a very delayed response.

Not a problem.

> I find your statement mildly astonishing. =A0What section(s) of
> the Standard do you believe such an access would violate
> (assuming as usual no alignment problems on the pointer
> conversion)?

I believe it would be a violation of the effective type rules.

Do you consider

  struct A { int a; };
  struct B { int b; int c; };
  int get_a(struct B b) { return ((struct A *) &b)->a; }

to be valid? Going by the literal wording of the effective type rules,
there is nothing to disallow this. The member b.b has type int, and is
accessed by an lvalue expression of type int. However, we know that
this is intended to be invalid, from examples in the standard, from
examples in DRs, and from the behaviour of real-world compilers when
fed the above. (If you disagree, please do let me know why.)

The effective type rules do not distinguish between structure and
array types, so if the above is invalid, the array equivalent must be
equally invalid.
0
truedfx (1926)
9/4/2011 8:06:39 PM
On Sep 4, 9:23=A0pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
> Harald van Dijk <true...@gmail.com> writes:
>
> [again my apologies for a much delayed response]

Again, no problem.

> > Consider a conversion sequence T * -> void * -> char * -> void * -> T
> > *, which happens with a custom implementation of qsort or similar
> > functions.
>
> That particular conversion sequence actually is guaranteed fairly
> directly by 6.3.2.3. =A0But I assume you mean to ask a more subtle
> question.

Oh? I can see that 6.3.2.3 guarantees that T * -> void * compares
equal to T * -> void * -> char * -> void *. But to compare equal does
not imply equivalence, so while the former may be safely converted
back to T *, how do you conclude the same for the latter?

> > Disclaimer: I'm not suggesting that relying on that conversion is a
> > bad idea. I'm saying the standard fails to state that relying on that
> > conversion is valid.
>
> It doesn't say it as directly as some people would like. =A0Different
> people make different assumptions about how the Standard should be
> interpreted. =A0My best understanding is, reading the Standard as WG14
> intends or expects it to be interpreted, the Standard actually does
> guarantee that pointer conversions work the way most (informed)
> people expect them to work. =A0(More details below...)

No argument there; for all practical purposes, we should treat more
pointer conversions as valid than the literal text of the standard
does. The problem is that different people come to different
conclusions about which other conversions should be valid. A recent
example was whether a direct pointer cast from struct { struct
{ int } } * to int * is valid. Good arguments can be made both for and
against.

> The notion of effective type is irrelevant to these questions
> about pointer conversion and array indexing.

See my reply to your other message.

[...]

> I will ask a question: =A0do you believe the Standard defines
> "pointers" or "pointer values" in such a way that valid pointers
> (that aren't null) point to some object?

Or to some function, presumably.

No, I do not. The standard requires that this assert passes:

  int i;
  double *p;
  p =3D (double *) &i;
  assert((int *) p =3D=3D &i);

However, that is the _only_ guarantee made about the value of p. Since
dereferencing p is not allowed in strictly conforming programs anyway,
the standard does not need to, and does not, address the question of
whether p points to any object at all.

>=A0I believe it does -
> pointers (even pointers of type (void*)) don't point "nowhere", they
> point at something (as before assuming they aren't null or don't
> have alignment problems).

The standard could have been written in such a way without any
inconsistencies, and it would have made sense if it had been, but I do
not think it is so, for the simple reason that I have not seen
anything to support this view.

>=A0The behavior of various pointer
> conversions follows from this implication.
>
> I know some people read some sections of 6.3.2.3 (notably, for
> example, the third sentence of 6.3.2.3p7) as limiting how pointer
> conversions work. =A0IMO that interpretation is incorrect; =A0these
> sentences are meant to add to what is allowed for pointer
> conversions, not take away from them.

The standard does not define the behaviour of pointer conversions
anywhere else (except for a special case with the memory allocation
functions, as you rightly noted). If the behaviour of a pointer
conversion is not defined by 6.3.2.3, and if it is not defined
anywhere else in the standard, it is undefined by omission.

> [snip sensible example]
> This conclusion follows from the principle that any valid pointer
> value (that isn't null) points to some object.

If any valid pointer value is null or points to some object, then your
conclusion is probably correct. If there are valid pointer values that
are neither null nor pointing to any object, then your conclusion is
still probably correct.

> I agree that the Standard doesn't say all this as clearly or as
> directly as I would like. =A0But I believe it is the most consistent
> reading of what the Standard does say, and also is how WG14
> intends and expects the Standard will be interpreted. =A0I don't
> have any specific examples to cite in support of this last part;
> as often happens with deeply held assumptions, it comes out more
> as a general sense from the writing (including the Standard, DR's,
> and the Rationale document primarily) than from any specific
> statement or set of statements.

Right. Ambiguities and omissions are a natural result of writing the
standard in English, so we have to make guesses and assumptions about
the intent.
0
truedfx (1926)
9/4/2011 8:29:49 PM
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Harald van Dijk <truedfx@gmail.com> writes:
>> On Jul 9, 6:48 pm, Tim Rentsch <t...@alumni.caltech.edu> wrote:
>>> Consider this example:
>>>
>>>   int i20[20];
>>>   int (*i45)[5] = (int (*)[5]) &i20; /* assume alignment is okay */
>>>   i45[1][7];
>>>
>>> I claim that the last line exhibits undefined behavior.  Or do
>>> you think the behavior here should be defined?
>>
>> I agree the behaviour is undefined, but for a different reason than
>> you: my point in this thread was that you cannot access an int[4][5]
>> as an int[20], but that works both ways: I believe you cannot access
>> an int[20] as an int[4][5] either.
>
> My apologies for a very delayed response.
>
> I find your statement mildly astonishing.  What section(s) of
> the Standard do you believe such an access would violate
> (assuming as usual no alignment problems on the pointer
> conversion)?

This doesn't *quite* address this specific case, but C99 J.2
(non-normative) says that the following has undefined behavior:

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

My (perhaps not entirely justified) inference from this is that
arrays have their declared types, and only their declared types;
trying to treat them as if they had a different type yields
undefined behavior.

What section(s) of the Standard actually define the behavior of
treating an int[20] as an int[4][5], or vice versa?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
9/4/2011 8:34:17 PM
Harald van Dijk <truedfx@gmail.com> writes:
[...]
> ... The standard requires that this assert passes:
>
>   int i;
>   double *p;
>   p = (double *) &i;
>   assert((int *) p == &i);
>
> However, that is the _only_ guarantee made about the value of p. Since
> dereferencing p is not allowed in strictly conforming programs anyway,
> the standard does not need to, and does not, address the question of
> whether p points to any object at all.
[...]

I don't believe the standard guarantees that at all.  It does
guarantee that a value of any pointer-to-object or pointer-to
incomplete type (i.e., any pointer other than a function pointer)
may be converted to void* and back again without loss of information.
There is no such guarantee for converting to double* and back again.

Consider a hypothetical system where CHAR_BIT == 8, int is 32
bits and requires 4-byte alignment, and double is 64 bits and
requires 8-byte alignment.  A machine word is 64 bits or 8 bytes.
The hardware supports two kinds of addresses: a word pointer that
specifies a 64-bit word and a (larger) byte pointer that consists
of a word pointer plus a byte offset within the word.  An int* is
a byte address.  Converting from int* to double* drops the offset;
converting back from double* to int* doesn't restore it.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
9/4/2011 10:40:32 PM
On 09/04/2011 04:29 PM, Harald van Dijk wrote:
....
> No, I do not. The standard requires that this assert passes:
> 
>   int i;
>   double *p;
>   p = (double *) &i;

You're assuming that the alignment requirements of double are no
stricter than those for int.

....
> If any valid pointer value is null or points to some object, then your
> conclusion is probably correct. If there are valid pointer values that
> are neither null nor pointing to any object, then your conclusion is
> still probably correct.

I don't see the relevance of that assumption. Even if the conversion of
a pointer to an object type to a pointer to a different object type
necessarily points at an object, that still does not help resolve the
question of which object it points at. In several special cases, the
standard does provide a guarantee, but not in the general case.
-- 
James Kuyper
0
jameskuyper (5635)
9/4/2011 10:45:23 PM
On Sep 5, 12:40=C2=A0am, Keith Thompson <ks...@mib.org> wrote:
> Harald van D=C4=B3k <true...@gmail.com> writes:
> [...]> ... The standard requires that this assert passes:
>
> > =C2=A0 int i;
> > =C2=A0 double *p;
> > =C2=A0 p =3D (double *) &i;
> > =C2=A0 assert((int *) p =3D=3D &i);
>
> > However, that is the _only_ guarantee made about the value of p. Since
> > dereferencing p is not allowed in strictly conforming programs anyway,
> > the standard does not need to, and does not, address the question of
> > whether p points to any object at all.
>
> [...]
>
> I don't believe the standard guarantees that at all.

As before in this thread, a part of the sentence is missing. The point
was that the standard requires that the assert passes, if &i is
suitably aligned for a pointer of type double *. Sorry for the
confusion.
0
truedfx (1926)
9/5/2011 5:15:02 AM
Harald van Dijk <truedfx@gmail.com> writes:
> On Sep 5, 12:40 am, Keith Thompson <ks...@mib.org> wrote:
>> Harald van Dijk <true...@gmail.com> writes:
>> [...]> ... The standard requires that this assert passes:
>>
>> >   int i;
>> >   double *p;
>> >   p = (double *) &i;
>> >   assert((int *) p == &i);
>>
>> > However, that is the _only_ guarantee made about the value of p. Since
>> > dereferencing p is not allowed in strictly conforming programs anyway,
>> > the standard does not need to, and does not, address the question of
>> > whether p points to any object at all.
>>
>> [...]
>>
>> I don't believe the standard guarantees that at all.
>
> As before in this thread, a part of the sentence is missing. The point
> was that the standard requires that the assert passes, if &i is
> suitably aligned for a pointer of type double *. Sorry for the
> confusion.

Hmm, I hadn't realized that round-trip pointer-to-pointer conversion is
guaranteed to yield the original value if the alignment is ok (C99
6.3.2.3p7).  (I'm sure I had read that paragraph; I just forgot about
it.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
9/5/2011 7:12:37 AM
Reply:

Similar Artilces:

1.1.1.1 ?
hi my firewall logs dropped packets from an internal IP address trying to contact 1.1.1.1 through port 9999. Any ideas whether 1.1.1.1 is valid IP? and what is port 9999?? thanks mike wrote: > hi > > my firewall logs dropped packets from an internal IP address trying to > contact 1.1.1.1 through port 9999. Any ideas whether 1.1.1.1 is valid > IP? and what is port 9999?? > thanks These trojans *BlitzNet*, *Backdoor.Oracle*, *Backdoor.Spadeace* uses port 9999 -- S.S. "StarScripter" <Star@privacy.net> wrote in message news:<bv8ejj$p54t3$1@ID-185702.news.uni-berlin.de>... > mike wrote: > > hi > > > > my firewall logs dropped packets from an internal IP address trying to > > contact 1.1.1.1 through port 9999. Any ideas whether 1.1.1.1 is valid > > IP? and what is port 9999?? > > thanks > > These trojans *BlitzNet*, *Backdoor.Oracle*, *Backdoor.Spadeace* uses port > 9999 thanks very much..will check it out ...

DeepForm 1.1.1
DeepForm allows an analyst to create a document (named Model) that specifies the structure and the contents of the XML document containing the corporate data. DeepForm does not requires any knowledge of the XML format by the user. The data model creation The application allows the user to compone his own model using a quick and easy interface. The analyst can create his own model by simply combining the "basic" elements of DeepForm: * fields (customizables); * tables; * sections. DeepForm allows to create new models by using parts of other models previuosly created. Every model is real a document taht can be added of notes and comments by the author without using a word processor editor. The main component is the section which together with the sub-sections allows to freely structure the data model in a gerarchic way. Every section can contain fields, tables and one or more sub-sections. DeepForm specifies the "formal" accuracy of data (syntax and type) through the automatic generation of rules written according to the international standard XML-Schema specified by the World Wide Web Consortium (W3C). The generation is automatic and does not require any previous knowledge on the XML language. More Info: http://www.tecnate.com/index.php?option=com_content&task=view&id=82&Itemid=166 Download URL: http://www.tecnate.com/dmdocuments/DPF11_Setup_SHW.exe Screenshot URL: http://www.tecnate.com/dmdoc...

RedNotebook 1.1.1
RedNotebook 1.1.1 has been released. You can get the tarball, the Windows installer and links to distribution packages at http://rednotebook.sourceforge.net/downloads.html What is RedNotebook? -------------------- RedNotebook is a **graphical journal** and diary helping you keep track of notes and thoughts. It includes a calendar navigation, customizable templates, export functionality and word clouds. You can also format, tag and search your entries. RedNotebook is available in the repositories of most common Linux distributions and a Windows installer is available. What's new? ----------- * Let user delete category with 'DELETE' key (LP:608717) * Sort categories alphabetically (LP:612859) * Fix: After clicking "Change the text" on an annotation, directly edit it (LP:612861) * Fix: Journal -> _Journal in menu * Fix: Do not clear entry when category is changed in new-entry dialog * Fix: restore left divider position * Fix: Use rednotebook website for retrieving newest version information (LP:621975) * Windows: Shrink installer size * Windows: Update gtk libs * Windows: New theme * Windows: New icons * New translations: * English (United Kingdom) * Norwegian Bokmal * Many translations updated Cheers, Jendrik ...

1--1
I don't understand why this works as expected: select * from games order by 2 but this doesn't: select * from games order by 1--1 The "order by" is completely ignored. On Wednesday January 21 2015 11:44, in comp.databases.mysql, "Kiuhnm Mnhuik" <gandalf23@mail.com> wrote: > I don't understand why this works as expected: > select * > from games > order by 2 > but this doesn't: > select * > from games > order by 1--1 > The "order by" is completely ignored. No, it isn...

both 1 and not-1?
Okay, maybe I'm getting too tired for tonight, but ... how can add_to_array *possibly* die with a filter violation (which it does)? Certainly, is_filtered doesn't modify $visit -- or does it? sub add_to_array{ my $self = shift; my $visit = shift; if ( not $self->is_filtered($visit) ){ if ( $self->is_filtered($visit) ){die ("FILTER VIOLATION\n");} } } sub is_filtered{ my $self = shift; my $visit = shift; while ( my ($field, $pattern) = each %{ $self->{_excludepatterns} } ){ if ( $visit->{$field} =~ $pattern){ return 1; } } return 0; } Many thanks, Michael Goerz "Michael Goerz" <news12@8439.e4ward.com> wrote in message news:4ns3s9Fbp1otU1@uni-berlin.de... > Okay, maybe I'm getting too tired for tonight, but ... how can > add_to_array *possibly* die with a filter violation (which it does)? > Certainly, is_filtered doesn't modify $visit -- or does it? > > sub add_to_array{ > my $self = shift; > my $visit = shift; > if ( not $self->is_filtered($visit) ){ > if ( $self->is_filtered($visit) ){die ("FILTER VIOLATION\n");} > } > } > > sub is_filtered{ > my $self = shift; > my $visit = shift; > while ( my ($field, $pattern) = each %{ $self->{_excludepatterns} } ){ > if ( $visit->{$field} =~ $pattern){ return 1; } > } > return 0; > } > > Many thanks...

Meaning of 1:1, 1:1 generalization, 1:n, 1:n non identifying, n:m
Hi All, I've been taking a look at DB Designer 4, and looking through the documentation (http://www.fabforce.net/dbdesigner4/doc/index.html) I am a little unclear on some of their nomenclature: '1:1' - Ok, one to one. Got it. '1:1 generalization' - Don't know this. Obviously different somehow from one to one, but how? '1:n' - One to many, I assume. '1:n non identifying' - Nonidentifying? What does this mean? 'n:m' - Many to many? Again, not sure. Can anyone help clarify? Thanks! -Josh Joshua Beall wrote: > I...

JDK 1.3.1/1.4/1.5
How can you display JDialog without the Close on the Top Right in any of these versions(JDK 1.3.1/1.4/1.5). The only thing it displays is the close button X and I don't want that? Thank you! vnssoftware wrote: > How can you display JDialog without the Close on the Top Right in any > of these versions(JDK 1.3.1/1.4/1.5). The only thing it displays is > the close button X and I don't want that? > > Thank you! Dialog.setUndecorated() since 1.4 -- Knute Johnson email s/nospam/knute/ Molon labe... ...

1.1, 1.2, 1.3 are all goners now
It seems, well, it doesn't seem but it is, well, it seems that the subject version of Workbenches won't be any more these, versions of Workbench, but versions of Amix. The Amiga's go for the Network. :-)) Have you seen that CDTV on amiga.jorg? That kind od schalametry for games, like some high tech heavily classic games will be played... Heyyyaaa!!! p.s. some piece of equipment, eh.. CD, floppy, installable HD, all, joysticks, joypads for CDTV, playing CDs and playing games. It's like you'll need a high class massive wood shelf for this, the CDs and for the - :( r...

MA(1)- GARCH (1,1)
Dear all, How do I fit MA(1) -GARCH(1,1) in SAS? Thanks Priyanka ...

[ANN]
Hi all, This is just a quick announcement to let y'all know that I've released = ptools=20 1.1.1 today. What is it? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Power tools for the File class. Additional methods include which, = whereis,=20 head, tail, middle, wc, null, nl_convert, touch and binary?. What's new? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D This release adds the File.null and File.binary? methods. The former = returns=20 the null device on your system The latter returns whether or not the = file in=20 question is a binary file (using a simple best-guess algorithm). Where is it? =3...

hours since 1-1-1
Dear IDL users: Is there an IDL function/program that converts the unidata time unit to more readable format? For example: hours since 1-1-1 17338824 -> Jan 1 1979. Thanks, Qian qian wrote: > Dear IDL users: > > Is there an IDL function/program that converts the unidata time unit to > more readable format? > > For example: hours since 1-1-1 17338824 -> Jan 1 1979. Oh no, not hours since 1-1-1 again! That must be the silliest ever date-time origin ever invented for modern data! I mean, what calendar were they using then and why should I have to care? Anywa...

Quickeo 1.1.1.3
Quickeo is for people who want to share their digital photos, videos and music with their friends, family and community - not the whole world. Quickeo is private file-sharing with a simple email. Quickeo lets you create rich multimedia newsletters in a matter of minutes. Quickeo is the only sharing service that lets you create a rich multimedia gallery (of videos, audios, images and other files) and choose exactly who may view each gallery through email. Quickeo allows you to present your multimedia content in a newsletter or album format, with video introduction (can be captured in ...

libshcodecs 1.1.1 Release
libshcodecs 1.1.1 Release ========================= libshcodecs is a library for controlling SH-Mobile hardware codecs. The [SH-Mobile][0] processor series includes a hardware video processing unit that supports MPEG-4 and H.264 encoding and decoding. libshcodecs is available under the terms of the GNU LGPL. The source archive, and more information about the library are available from: https://oss.renesas.com/modules/document/?libshcodecs New in this release =================== This is a brown paper bag release, including a missing file (display.h) and fixes for compile warnings and other cleanups. Following proper procedure, this new tarball has been generated with "make distcheck". Details ------- This release includes the following changes since version 1.1.0: Conrad Parker (3): add missing display.h to distribution fix compile warnings throughout Release 1.1.1 Phil Edworthy (1): Clean up: Remove unused symbols configure.ac | 2 +- src/libshcodecs/Version_script.in | 23 +++-------------------- src/libshcodecs/m4driverif.c | 12 +----------- src/tools/Makefile.am | 1 + src/tools/capture.c | 2 +- src/tools/display.c | 6 ++++++ src/tools/shcodecs-record.c | 4 ++-- 7 files changed, 15 insertions(+), 35 deletions(-) [0]: http://www.renesas.com/fmwk.jsp?cnt=sh_mobile_family_landing.jsp&fp=/pr...

[Ann] UIHierarchy 1.1.1 is out!
Hi all, Some news of UIHierarchy, the AWT/Swing containement hierarchy helper library. -- Release 1.1.1 is out -- * What is UIHierarchy: The UIHierarchy library aims at simplifying the development of user interfaces made in AWT or Swing. It simplifies code syntax to match the mental picture of containement hierarchy, which makes it easier to develop and maintain small to complex user interfaces. License terms are Sun Public License 1.0. * Project pages: The homepage is: http://chrriis.brainlex.com/projects/uihierarchy. The SourceForge project: http://sourceforge.net/projects/uihierarchy. The Proposed dowloads are: - UIHierarchy.zip: contains the library "UIHierarchy.jar" - UIHierarchySrc.zip: contains the sources of the library, and the javadoc. You probably need the NanoXml parser to compile the XML helper class. * Documentation: Some documentation is available in the project homepage, along with examples. * Changes in Release 1.1.1: - FormLayout is supported. - Component creators to support any kind of automatic component creation. - New build construct with more enforcement using the new UIH class. - Complete rewrite of UIHierarchy to use UIH internally. - Nested arrays construct was useless, so it is removed. API gets easier. - Print was mixing "out" and "err" output streams. Now fixed. - Print could not handle null layout managers. Now fixed. - Print: package names are removed to shorten the clas...

XOTcl 1.1.1 available
Dear Tcl community, i am pleased to announce the general availability of XOTcl 1.1.1. Changes (mostly portability and build improvements) relative to 1.1.0 are: - Compiles out of the box for * Mac OS X (many thanks to Daniel Steffen) * freebsd 4.9 (many thanks to Marc Spitzer) - configure can run outside of xotcl-tree and can install to a different directory. Example: % mkdir -p /tmp/xotcl/unix % cd /tmp/xotcl/unix % ~/xotcl-1.1.1/unix/configure --with-all % make % make test % make install DESTDIR=/tmp - several fixes and improvements such as * added option --with-tkinclude for configure (only needed when built with optional --with-xowish) * fixes to make gdbm work when compiled with threads enabled * fix for initialization of stubtables in gdbm * fixes for HTTP support (return format of values in HTTP OPTION command made windows explorer hang) * easy provision for redirects in HTTP server best regards -gustaf neumann & uwe zdun Download is available @ http://media.wu-wien.ac.at/download.html -- David Gravereaux <davygrvy@pobox.com> [species: human; planet: earth,milkyway(western spiral arm),alpha sector] ...

ANN: Twisted 1.1.1
Twisted is an event-driven networking framework for server and client applications. For more information, visit http://www.twistedmatrix.com, join the list http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python or visit us on #twisted at irc.freenode.net. The Twisted from Scratch tutorial is a good starting point for learning Twisted: http://twistedmatrix.com/documents/howto/tutorial What's New in 1.1.1 =================== - Many bug fixes and minor improvements. - MSN protocol support updated to support MSN8P. - Conch SSH client now supports SSH auth agent. What is Twisted? ================ Twisted is an event-driven framework for building networked clients and servers. It contains a powerful and simple networking core, a full-featured suite of interoperable protocols, among them a powerful web server and applications framework. ...

Installing subversion 1.1.1
Ok, I just can't seem to get this to work on upgrading. cd /usr/ports/www/apache2 make clean make WITH_PROXY_MODULES=yes WITH_SSL_MODULES=yes \\ WITH_BERKELEYBD=db4 make deinstall make reinstall cd /usr/ports/devel/subversion make clean sudo make WITH_MOD_DAV_SVN="yes" WITH_PYTHON="yes" WITH_PERL="yes" Produces this error: You should build `www/apache2' with db4 support to use subversion with it. Please rebuild `www/apache2' with option `WITH_BERKELEYDB=(db4|db41|db42)' and try again. do I also have to do apr-svn as well? -- Kirk Job-Sluder "The square-jawed homunculi of Tommy Hilfinger ads make every day an existential holocaust." --Scary Go Round Kirk Job-Sluder wrote: > Ok, I just can't seem to get this to work on upgrading. > > cd /usr/ports/www/apache2 > make clean > make WITH_PROXY_MODULES=yes WITH_SSL_MODULES=yes \\ > WITH_BERKELEYBD=db4 doh! ...

ADTPro 1.1.1 Released
Some goodies for our /// friends, plus lots of movement in the UDP/ Uthernet arena. See: http://adtpro.sourceforge.net New functionality: * [Client] SOS version can use Ethernet UDP transport via the Uthernet card (http://a2retrosystems.com/) * [Client] SOS version can format media * [Server] Apple /// computers can be bootstrapped from bare metal over their built-in serial ports Bug fixes: * [Client] Occasional Ethernet "hang" during transfer * [Client] Exiting the Ethernet configuration screen via the Return key but without saving to disk caused changes to ...

VMware Fusion 1.1.1 out
See: <http://www.vmware.com/products/fusion/> Ian -- Ian Robinson, Belfast, UK <http://www.canicula.com/wp/> ...

ANN: pyFltk-1.1.1
We are happy to announce a new release of pyFltk, the Python bindings for FLTK. This release supports FLTK-1.1.7 and Python 2.4 and 2.5. FLTK is a lightweight cross-platform GUI toolkit with a very small footprint. pyFltk applications are very simple and intuitive, making it a good choice for small to medium applications that want to get up to speed quickly. Changes in this release include various bug fixes, improved memory management, and the fixing of several compilation issues. Also, some preliminary documentation was added, see test/preface.html. This release can be downloaded from the project home page: http://pyfltk.sourceforge.net Have fun! Andreas http://pyfltk.sourceforge.net ...

build jdk 1.3.1 or 1.4.1 on freebsd 5.1-release :(
Hi, I'm not able to build sun java jdk 1.3.1 on FreeBSD 5.1 release, here is the error message: ===> Applying FreeBSD patches for jdk-1.3.1p8_2 ===> jdk-1.3.1p8_2 depends on executable: gm4 - found ===> jdk-1.3.1p8_2 depends on executable: zip - found ===> jdk-1.3.1p8_2 depends on file: /usr/X11R6/lib/libXm.so - found ===> jdk-1.3.1p8_2 depends on executable: msgfmt - found ===> jdk-1.3.1p8_2 depends on file: /usr/local/diablo-jdk1.3.1/bin/javac - not found ===> Verifying install for /usr/local/diablo-jdk1.3.1/bin/javac in /usr/ports/java/diablo-jdk13 ===> diablo-jdk-1.3.1.0 : Because of licensing restrictions, you must fetch the distribution manually. Please access http://www.FreeBSDFoundation.org/cgi-bin/download.cgi?package=diablo-caffe-1.3.1-0.tar.bz2 with a web browser and "Accept" the End User License Agreement for "Caffe Diablo ". Please place the downloaded diablo-caffe-1.3.1-0.tar.bz2 in /usr/ports/distfiles. ..*** Error code 1 Stop in /usr/ports/java/diablo-jdk13. *** Error code 1 Stop in /usr/ports/java/jdk13. ----------------------------------------------------- It 's mentionned that I should download diablo-caffe-1.3.1etc... but this release is not for FreeBSD5 So I tried to install jdk 1.4.1 and here is the output: ------------------------------------------------------------------------------ External File/Binary Locations: HOTSPOT_SERVER_PAT...

Serialization between Java 1.1.4 and Java 1.4.1
Hello, It seems to me to be in some kinda trouble. I wanted to implement communication between Java applet and Server through sockets and Serialization. So, I serialize Object, send it to server which deserialize it with no problems. In other direction problems came out since Object serialized under Java 1.4.1 seems to be not deserializable under Java 1.1.4. (MS VM). If applet si run under J2, there are no problems, but I cannot push people to download some 15MB of new JRE just to accomplish my requirements, especially if applet needs not implementation of features of new JRE... ...

Looking for SNMP-5.1.1/NetSNMP-5.1.1
CPAN is not up-to-date with either of theses (the latest is SNMP-4.0.2). Does anyone know of a reputable and up-to-date site for either SNMP-5.1.1 oe NetSNMP-5.1.1? Thanks! Joe Cipale >>>>> On 29 Apr 2005 14:48:16 -0700, joe.cipale@radisys.com said: joe> CPAN is not up-to-date with either of theses (the latest is joe> SNMP-4.0.2). Does anyone know of a reputable and up-to-date site joe> for either SNMP-5.1.1 oe NetSNMP-5.1.1? You should download the SNMP perl module that is contained within the SNMP source code for net-snmp. Get the net-snmp version you want to use from http://www.net-snmp.org/download and compile using --with-perl-modules (or --enable-embedded-perl). (the SNMP module is highly linked to the version of the net-snmp library and thus the perl module shouldn't be downloaded independently any longer). -- "In the bathtub of history the truth is harder to hold than the soap, and much more difficult to find." -- Terry Pratchett ...

Controlling VI Logger 1.1.1 with LabVIEW 7.1
I have LabVIEW 7.1 on my system and installed VI Logger (1.1 them upgraded to 1.1.1). I would like to programatically control VI Logger with LabVIEW. There are references to VIs under the Advanced pallate to do just that, but I cannot find them or any help files to explain what to do. Where do I find these VIs? ...

Web resources about - Alignment of foo[1][1][1][1] - comp.lang.c

Danny Foo - Malaysia web designer
Danny Foo is a Malaysian web designer and blogger based in Kuala Lumpur.

Foo Fighters - The Official Foo Fighters Site
Welcome to the official Foo Fighters website featuring Foo Fighters news, music, videos, album info, tour dates, and more.

Touch Foo - iOS Games
Touch Foo About Contact Swordigo Soosiz Games By Touch Foo © 2009 - 2012 Ville Mäkynen and Tuomas Mäkynen. All rights reserved.

Foo Fighters (album) - Wikipedia, the free encyclopedia
Foo Fighters is the debut album by American alternative rock band Foo Fighters , released on July 4, 1995 by Capitol Records through Dave Grohl ...

Foo Fighters - Hot Buns
Hot Buns & Tour Dates

Foo Factory
Our first ever fantastically simple app launched onto the iTunes App Store. Aimed at 2yr old children it has a set of cartoon animals and a little ...

HBO to Live-Stream Foo Fighters Concert on Facebook
Free Foo Fighters ? HBO is marking the upcoming debut of new series Foo Fighters: Sonic Highways by presenting the live stream of the band’s ...

Foo Fighters RVA (@foofighters_rva) on Twitter
Sign in Sign up To bring you Twitter, we and our partners use cookies on our and other websites. Cookies help personalize Twitter content, tailor ...

The Foos: Code for an Hour FREE girls and boys educational app on the App Store on iTunes
Get The Foos: Code for an Hour FREE girls and boys educational app on the App Store. See screenshots and ratings, and read customer reviews. ...

Socializing Young Nerds @ Foo Camp 08 - Flickr - Photo Sharing!
Christy Canida and I ran a session at Foo Camp this year about Christy Canida and I ran a session at Foo Camp this year about using the Internet ...

Resources last updated: 3/24/2016 4:37:09 PM