Topic: Adding C99 Flexible Arrays


Author: Daryle Walker <darylew@gmail.com>
Date: Thu, 9 Jan 2014 03:02:34 -0800 (PST)
Raw View
------=_Part_194_24955898.1389265354294
Content-Type: text/plain; charset=ISO-8859-1

Maybe I'm too sleep deprived, but I tried to write a quick proposal to a
flexible arrays from C99, and got caught up in figuring out all the
subtleties.  So maybe sparking a discussion here will help organize all the
ideas, and get stuff I may be missing.

Flexible arrays were a way to canonize the "struct hack."  The last member
of your struct is an array of unknown bound.  You then malloc a space of
the sizeof(your struct) + extra array elements.  Maybe someone here can
explain it better.  I don't need it; I just want to improve C++ vs. C
compatibility.


   - An unbound class type has one of the following as its last-declared
   non-static data member:
      - an array of unknown bound
      - an object of a (prior) unbound class type
   - Does the above mean that the unbound class type needs all its
   non-static data members to be of the same access level?
   - Does the above mean we should specify that the unbound class type
   needs to be standard layout?
   - The unbounded sub-object must be named.
   - If the unbounded sub-object is an array, there must be at least one
   named non-static data member before it.
   - The above means that a union cannot use an array of unknown bound.
   - A union may have one or more non-static data members of unbound class
   type.  (Need constructors or C99's member delegation here.)
   - An unbound class type cannot be the element type of an array.
   - Do we need to add a type-trait for this?
   - Does an unbound class type need to be considered incomplete (in
   general)?  Is complete vs. incomplete types actually defined anywhere?  I
   think sections 3.2 and 3.9 have something.  Is there any part that
   describes abstract class types are always incomplete?  (Maybe unbound class
   types could go in that same section.)
   - Should it be restricted to games with malloc, or should we add new and
   direct object support?  If the former, then the types involved need to be
   POD.  If the latter, then we need to mandate initialization whenever an
   unbound class object is allocated or defined.  (An in-class-definition
   brace-or-equal initializer as a last resort is OK.)
   - Is it possible to specify that an unbound class type is incomplete
   usually but becomes complete when a object has an initializer (that gives
   enough information to determine the size)?
   - If an unbound class type uses constructors, then either the unbound
   member has a brace-or-equal initializer or every non-delgating constructor
   must mention the unbound member.
   - I guess the implicit default-, copy-, and move-constructors have to be
   marked deleted by default.  And the copy- and move-assignment operators
   have to be deleted too.
   - But it should be possible to initialize an unbound class object with
   another if its size is known.  This limits the source objects to ones
   statically defined in the same (or higher) scope.
   - From the above two points, maybe we need the unbound class type to be
   trivially-copyable (and the copy- and move-constructors are implicitly
   defined as defaulted).
   - There's a section in Clause 12 about abstract class types.  Do we need
   a section for unbound class types? Should it go into Clause 9 instead?
   - The part in 9.2/9 about no incomplete members has to be modified.
   - If an unbound class object uses aggregate initialization, then the
   initialization has to cover the unbound member sub-object if it doesn't
   have a brace-or-equal initializer.
   - Need to figure out all the sections to be modified.
   - Probably stuff I've forgotten or haven't considered yet....

Just a initial spew of thoughts.

Daryle W.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_194_24955898.1389265354294
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Maybe I'm too sleep deprived, but I tried to write a quick=
 proposal to a flexible arrays from C99, and got caught up in figuring out =
all the subtleties. &nbsp;So maybe sparking a discussion here will help org=
anize all the ideas, and get stuff I may be missing.<div><br></div><div>Fle=
xible arrays were a way to canonize the "struct hack." &nbsp;The last membe=
r of your <font face=3D"courier new, monospace">struct</font> is an array o=
f unknown bound. &nbsp;You then <font face=3D"courier new, monospace">mallo=
c</font> a space of the <font face=3D"courier new, monospace">sizeof</font>=
(your struct) + extra array elements. &nbsp;Maybe someone here can explain =
it better. &nbsp;I don't need it; I just want to improve C++ vs. C compatib=
ility.<br><div><br></div><div><ul><li><span style=3D"line-height: normal;">=
An unbound class type has one of the following as its last-declared non-sta=
tic data member:</span></li><ul><li><span style=3D"line-height: normal;">an=
 array of unknown bound</span></li><li><span style=3D"line-height: normal;"=
>an object of a (prior) unbound class type</span></li></ul><li><span style=
=3D"line-height: normal;">Does the above mean that the unbound class type n=
eeds all its non-static data members to be of the same access level?</span>=
</li><li><span style=3D"line-height: normal;">Does the above mean we should=
 specify that the unbound class type needs to be standard layout?</span></l=
i><li><span style=3D"line-height: normal;">The unbounded sub-object must be=
 named.</span></li><li><span style=3D"line-height: normal;">If the&nbsp;unb=
ounded sub-object is an array, there must be at least one named non-static =
data member before it.</span></li><li><span style=3D"line-height: normal;">=
The above means that a union cannot use an array of unknown bound.</span></=
li><li><span style=3D"line-height: normal;">A union may have one or more no=
n-static data members of unbound class type. &nbsp;(Need constructors or C9=
9's member delegation here.)</span></li><li><span style=3D"line-height: nor=
mal;">An unbound class type cannot be the element type of an array.</span><=
/li><li><span style=3D"line-height: normal;">Do we need to add a type-trait=
 for this?</span></li><li><span style=3D"line-height: normal;">Does an unbo=
und class type need to be considered incomplete (in general)? &nbsp;Is comp=
lete vs. incomplete types actually defined anywhere? &nbsp;I think sections=
 3.2 and 3.9 have something. &nbsp;Is there any part that describes abstrac=
t class types are always incomplete? &nbsp;(Maybe unbound class types could=
 go in that same section.)</span></li><li><span style=3D"line-height: norma=
l;">Should it be restricted to games with <font face=3D"courier new, monosp=
ace">malloc</font>, or should we add <font face=3D"courier new, monospace">=
new</font> and direct object support? &nbsp;If the former, then the types i=
nvolved need to be POD. &nbsp;If the latter, then we need to mandate initia=
lization whenever an unbound class object is allocated or defined. &nbsp;(A=
n in-class-definition brace-or-equal initializer as a last resort is OK.)</=
span></li><li><span style=3D"line-height: normal;">Is it possible to&nbsp;s=
pecify&nbsp;that an unbound class type is incomplete usually but becomes co=
mplete when a object has an initializer (that gives enough information to d=
etermine the size)?</span></li><li><span style=3D"line-height: normal;">If =
an unbound class type uses constructors, then either the unbound member has=
 a brace-or-equal initializer or every non-delgating constructor must menti=
on the unbound member.</span></li><li><span style=3D"line-height: normal;">=
I guess the implicit default-, copy-, and move-constructors have to be mark=
ed <font face=3D"courier new, monospace">delete</font>d by default. &nbsp;A=
nd the copy- and move-assignment operators have to be <font face=3D"courier=
 new, monospace">delete</font>d too.</span></li><li><span style=3D"line-hei=
ght: normal;">But it should be possible to initialize an unbound class obje=
ct with another if its size is known. &nbsp;This limits the source objects =
to ones statically defined in the same (or higher) scope.</span></li><li><s=
pan style=3D"line-height: normal;">From the above two points, maybe we need=
 the unbound class type to be trivially-copyable (and the copy- and move-co=
nstructors are implicitly defined as <font face=3D"courier new, monospace">=
default</font>ed).</span></li><li><span style=3D"line-height: normal;">Ther=
e's a section in Clause 12 about abstract class types. &nbsp;Do we need a s=
ection for unbound class types? Should it go into Clause 9 instead?</span><=
/li><li><span style=3D"line-height: normal;">The part in 9.2/9 about no inc=
omplete members has to be modified.</span></li><li><span style=3D"line-heig=
ht: normal;">If an unbound class object uses aggregate initialization, then=
 the initialization has to cover the unbound member sub-object if it doesn'=
t have a brace-or-equal initializer.</span></li><li><span style=3D"line-hei=
ght: normal;">Need to figure out all the sections to be modified.</span></l=
i><li><span style=3D"line-height: normal;">Probably stuff I've forgotten or=
 haven't considered yet....</span></li></ul>Just a initial spew of thoughts=
..</div></div><div><br></div><div>Daryle W.</div><div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_194_24955898.1389265354294--

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Thu, 09 Jan 2014 21:15:11 +0100
Raw View
On 01/09/2014 12:02 PM, Daryle Walker wrote:
> Maybe I'm too sleep deprived, but I tried to write a quick proposal to a =
flexible arrays from C99, and got caught up in figuring out all the subtlet=
ies.  So maybe sparking a discussion here will help organize all the ideas,=
 and get stuff I may be missing.
>=20
> Flexible arrays were a way to canonize the "struct hack."  The last membe=
r of your struct is an array of unknown bound.  You then malloc a space of =
the sizeof(your struct) + extra array elements.  Maybe someone here can exp=
lain it better.  I don't need it; I just want to improve C++ vs. C compatib=
ility.
>=20
>   * An unbound class type has one of the following as its last-declared n=
on-static data member:
>       o an array of unknown bound
>       o an object of a (prior) unbound class type

Is this quoting C99 semantics, or the desirable feature set for C++?

>   * Does the above mean that the unbound class type needs all its non-sta=
tic data members to be of the same access level?

If you have access specifiers in between, the compiler is allowed to reorde=
r members.

>   * Does the above mean we should specify that the unbound class type nee=
ds to be standard layout?

The feature (including the requirement to use "malloc" to allocate it) is
somewhat at odds with the constructor approach of C++ for initializing clas=
ses.
But no, I don't think there is an inherent technical requirement that the
class type be standard layout.  (The compiler should refrain from reorderin=
g
the last unbound array member.)

>   * The unbounded sub-object must be named.

Other than unnamed bit-fields, I thought all members need to be named.

>   * If the unbounded sub-object is an array, there must be at least one n=
amed non-static data member before it.

Why?

>   * The above means that a union cannot use an array of unknown bound.

Which is a fine restriction by itself.

>   * A union may have one or more non-static data members of unbound class=
 type.  (Need constructors or C99's member delegation here.)

>   * An unbound class type cannot be the element type of an array.

Yes.

>   * Do we need to add a type-trait for this?

The more interesting question is: What happens if I attempt to define a var=
iable
of such class type on the stack or globally (at namespace scope)?
What happens if I call  new MyType   for it?

>   * Does an unbound class type need to be considered incomplete (in gener=
al)?

Then you can't have objects of such a type (similar to void). That sounds w=
rong.

>   * Should it be restricted to games with malloc, or should we add new an=
d direct object support?  If the former, then the types involved need to be=
 POD.  If the latter, then we need to mandate initialization whenever an un=
bound class object is allocated or defined.  (An in-class-definition brace-=
or-equal initializer as a last resort is OK.)

If you want a C++ approach to the underlying problem that these "unbound cl=
ass types" try to solve,
you should probably start from scratch in the design space.  If it turns ou=
t we can usefully extend
the C99 syntax, fine, but requiring use of "malloc" is certainly not the wa=
y to go for C++.

>   * Is it possible to specify that an unbound class type is incomplete us=
ually but becomes complete when a object has an initializer (that gives eno=
ugh information to determine the size)?

Influencing "type" by defining an object and initializing it sounds misguid=
ed.

Jens

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Thu, 9 Jan 2014 12:40:40 -0800
Raw View
--047d7b2e4d52cd80cc04ef8fa100
Content-Type: text/plain; charset=ISO-8859-1

>Other than unnamed bit-fields, I thought all members need to be named.

E.g. anonymous structs and unions are in C++11 to my understanding. That
is, this is valid:

class Foo
{
    union
    {
        struct
        {
            int a; int b;
        };
        struct
        {
            char var;
            char example[7];
        };
    };
};

is valid if I'm not mistaken.See e.g. N3797 9.5 [class.union]/5:

A union of the form
union { member-specification } ;

is called an anonymous union.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Thu, Jan 9, 2014 at 12:15 PM, Jens Maurer <Jens.Maurer@gmx.net> wrote:

> On 01/09/2014 12:02 PM, Daryle Walker wrote:
> > Maybe I'm too sleep deprived, but I tried to write a quick proposal to a
> flexible arrays from C99, and got caught up in figuring out all the
> subtleties.  So maybe sparking a discussion here will help organize all the
> ideas, and get stuff I may be missing.
> >
> > Flexible arrays were a way to canonize the "struct hack."  The last
> member of your struct is an array of unknown bound.  You then malloc a
> space of the sizeof(your struct) + extra array elements.  Maybe someone
> here can explain it better.  I don't need it; I just want to improve C++
> vs. C compatibility.
> >
> >   * An unbound class type has one of the following as its last-declared
> non-static data member:
> >       o an array of unknown bound
> >       o an object of a (prior) unbound class type
>
> Is this quoting C99 semantics, or the desirable feature set for C++?
>
> >   * Does the above mean that the unbound class type needs all its
> non-static data members to be of the same access level?
>
> If you have access specifiers in between, the compiler is allowed to
> reorder members.
>
> >   * Does the above mean we should specify that the unbound class type
> needs to be standard layout?
>
> The feature (including the requirement to use "malloc" to allocate it) is
> somewhat at odds with the constructor approach of C++ for initializing
> classes.
> But no, I don't think there is an inherent technical requirement that the
> class type be standard layout.  (The compiler should refrain from
> reordering
> the last unbound array member.)
>
> >   * The unbounded sub-object must be named.
>
> Other than unnamed bit-fields, I thought all members need to be named.
>
> >   * If the unbounded sub-object is an array, there must be at least one
> named non-static data member before it.
>
> Why?
>
> >   * The above means that a union cannot use an array of unknown bound.
>
> Which is a fine restriction by itself.
>
> >   * A union may have one or more non-static data members of unbound
> class type.  (Need constructors or C99's member delegation here.)
>
> >   * An unbound class type cannot be the element type of an array.
>
> Yes.
>
> >   * Do we need to add a type-trait for this?
>
> The more interesting question is: What happens if I attempt to define a
> variable
> of such class type on the stack or globally (at namespace scope)?
> What happens if I call  new MyType   for it?
>
> >   * Does an unbound class type need to be considered incomplete (in
> general)?
>
> Then you can't have objects of such a type (similar to void). That sounds
> wrong.
>
> >   * Should it be restricted to games with malloc, or should we add new
> and direct object support?  If the former, then the types involved need to
> be POD.  If the latter, then we need to mandate initialization whenever an
> unbound class object is allocated or defined.  (An in-class-definition
> brace-or-equal initializer as a last resort is OK.)
>
> If you want a C++ approach to the underlying problem that these "unbound
> class types" try to solve,
> you should probably start from scratch in the design space.  If it turns
> out we can usefully extend
> the C99 syntax, fine, but requiring use of "malloc" is certainly not the
> way to go for C++.
>
> >   * Is it possible to specify that an unbound class type is incomplete
> usually but becomes complete when a object has an initializer (that gives
> enough information to determine the size)?
>
> Influencing "type" by defining an object and initializing it sounds
> misguided.
>
> Jens
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7b2e4d52cd80cc04ef8fa100
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><span style=3D"font-family:arial,sans-serif;font-size:13px=
">&gt;Other than unnamed bit-fields, I thought all members need to be named=
..</span><br><div><span style=3D"font-family:arial,sans-serif;font-size:13px=
"><br>

</span></div><div><span style=3D"font-family:arial,sans-serif;font-size:13p=
x">E.g. anonymous structs and unions are in C++11 to my understanding. That=
 is, this is valid:</span></div><div><span style=3D"font-family:arial,sans-=
serif;font-size:13px"><br>

</span></div><div><span style=3D"font-family:arial,sans-serif;font-size:13p=
x">class Foo</span></div><div><span style=3D"font-family:arial,sans-serif;f=
ont-size:13px">{</span></div><div><span style=3D"font-family:arial,sans-ser=
if;font-size:13px">=A0 =A0 union</span></div>

<div><font face=3D"arial, sans-serif">=A0 =A0 {</font></div><div><font face=
=3D"arial, sans-serif">=A0 =A0 =A0 =A0 struct</font></div><div><font face=
=3D"arial, sans-serif">=A0 =A0 =A0 =A0 {</font></div><div><font face=3D"ari=
al, sans-serif">=A0 =A0 =A0 =A0 =A0 =A0 int a; int b;</font></div>

<div><font face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 };</font></div><div><=
font face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 struct</font></div><div><fo=
nt face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 {<br></font></div><div><font =
face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 =A0 =A0 char var;</font></div>

<div><font face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 =A0 =A0 char example[=
7];</font></div><div><font face=3D"arial, sans-serif">=A0 =A0 =A0 =A0 };</f=
ont></div><div><font face=3D"arial, sans-serif">=A0 =A0 };</font></div><div=
><font face=3D"arial, sans-serif">};</font></div>

<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">is valid if I&#39;m not mistaken.See e.g. N3797 9.5 [clas=
s.union]/5:</font></div><div><font face=3D"arial, sans-serif"><br></font></=
div>

<div><font face=3D"arial, sans-serif">A union of the form</font></div><div>=
<font face=3D"arial, sans-serif">union { member-specification } ;</font></d=
iv><div><font face=3D"arial, sans-serif"><br></font></div><div><font face=
=3D"arial, sans-serif">is called an anonymous union.</font></div>

</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/"=
 target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"=
http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://=
stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Thu, Jan 9, 2014 at 12:15 PM, Jens Ma=
urer <span dir=3D"ltr">&lt;<a href=3D"mailto:Jens.Maurer@gmx.net" target=3D=
"_blank">Jens.Maurer@gmx.net</a>&gt;</span> wrote:<br><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex">

<div class=3D"im">On 01/09/2014 12:02 PM, Daryle Walker wrote:<br>
&gt; Maybe I&#39;m too sleep deprived, but I tried to write a quick proposa=
l to a flexible arrays from C99, and got caught up in figuring out all the =
subtleties. =A0So maybe sparking a discussion here will help organize all t=
he ideas, and get stuff I may be missing.<br>


&gt;<br>
&gt; Flexible arrays were a way to canonize the &quot;struct hack.&quot; =
=A0The last member of your struct is an array of unknown bound. =A0You then=
 malloc a space of the sizeof(your struct) + extra array elements. =A0Maybe=
 someone here can explain it better. =A0I don&#39;t need it; I just want to=
 improve C++ vs. C compatibility.<br>


&gt;<br>
</div>&gt; =A0 * An unbound class type has one of the following as its last=
-declared non-static data member:<br>
&gt; =A0 =A0 =A0 o an array of unknown bound<br>
&gt; =A0 =A0 =A0 o an object of a (prior) unbound class type<br>
<br>
Is this quoting C99 semantics, or the desirable feature set for C++?<br>
<br>
&gt; =A0 * Does the above mean that the unbound class type needs all its no=
n-static data members to be of the same access level?<br>
<br>
If you have access specifiers in between, the compiler is allowed to reorde=
r members.<br>
<br>
&gt; =A0 * Does the above mean we should specify that the unbound class typ=
e needs to be standard layout?<br>
<br>
The feature (including the requirement to use &quot;malloc&quot; to allocat=
e it) is<br>
somewhat at odds with the constructor approach of C++ for initializing clas=
ses.<br>
But no, I don&#39;t think there is an inherent technical requirement that t=
he<br>
class type be standard layout. =A0(The compiler should refrain from reorder=
ing<br>
the last unbound array member.)<br>
<br>
&gt; =A0 * The unbounded sub-object must be named.<br>
<br>
Other than unnamed bit-fields, I thought all members need to be named.<br>
<br>
&gt; =A0 * If the unbounded sub-object is an array, there must be at least =
one named non-static data member before it.<br>
<br>
Why?<br>
<br>
&gt; =A0 * The above means that a union cannot use an array of unknown boun=
d.<br>
<br>
Which is a fine restriction by itself.<br>
<br>
&gt; =A0 * A union may have one or more non-static data members of unbound =
class type. =A0(Need constructors or C99&#39;s member delegation here.)<br>
<br>
&gt; =A0 * An unbound class type cannot be the element type of an array.<br=
>
<br>
Yes.<br>
<br>
&gt; =A0 * Do we need to add a type-trait for this?<br>
<br>
The more interesting question is: What happens if I attempt to define a var=
iable<br>
of such class type on the stack or globally (at namespace scope)?<br>
What happens if I call =A0new MyType =A0 for it?<br>
<br>
&gt; =A0 * Does an unbound class type need to be considered incomplete (in =
general)?<br>
<br>
Then you can&#39;t have objects of such a type (similar to void). That soun=
ds wrong.<br>
<br>
&gt; =A0 * Should it be restricted to games with malloc, or should we add n=
ew and direct object support? =A0If the former, then the types involved nee=
d to be POD. =A0If the latter, then we need to mandate initialization whene=
ver an unbound class object is allocated or defined. =A0(An in-class-defini=
tion brace-or-equal initializer as a last resort is OK.)<br>


<br>
If you want a C++ approach to the underlying problem that these &quot;unbou=
nd class types&quot; try to solve,<br>
you should probably start from scratch in the design space. =A0If it turns =
out we can usefully extend<br>
the C99 syntax, fine, but requiring use of &quot;malloc&quot; is certainly =
not the way to go for C++.<br>
<br>
&gt; =A0 * Is it possible to specify that an unbound class type is incomple=
te usually but becomes complete when a object has an initializer (that give=
s enough information to determine the size)?<br>
<br>
Influencing &quot;type&quot; by defining an object and initializing it soun=
ds misguided.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
Jens<br>
</font></span><div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b2e4d52cd80cc04ef8fa100--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 09 Jan 2014 12:55:51 -0800
Raw View
On quinta-feira, 9 de janeiro de 2014 21:15:11, Jens Maurer wrote:
> >   * An unbound class type has one of the following as its last-declared
non-static data member:
> >       o an array of unknown bound
> >       o an object of a (prior) unbound class type
>
> Is this quoting C99 semantics, or the desirable feature set for C++?
>
> >   * Does the above mean that the unbound class type needs all its
> >   non-static data members to be of the same access level?
> If you have access specifiers in between, the compiler is allowed to reorder
> members.

This leads to the next question:

> >   * Does the above mean we should specify that the unbound class type
> >   needs to be standard layout?
> The feature (including the requirement to use "malloc" to allocate it) is
> somewhat at odds with the constructor approach of C++ for initializing
> classes. But no, I don't think there is an inherent technical requirement
> that the class type be standard layout.  (The compiler should refrain from
> reordering the last unbound array member.)

Two solutions to the problem: either require the compiler to leave the unbound
member last or require the aggregate to be standard layout.

> >   * The unbounded sub-object must be named.
>
> Other than unnamed bit-fields, I thought all members need to be named.

He's probably thinking of anonymous unions.

Is this allowed?

struct X
{
 int i;
 union {
  double d;
  char buf[0];
 };
};

And, for that matter, is this allowed?

struct X
{
 int i;
 union {
  double d[0];
  char buf[0];
 };
};

> >   * If the unbounded sub-object is an array, there must be at least one
> >   named non-static data member before it.
> Why?

I'm interested too. Why couldn't I remove the int i in the structs above?

You may argue that it's rather pointless to have a struct whose only member is
an array of arbitrary size. The struct is unnecessary, you could just use a
pointer.

> >   * An unbound class type cannot be the element type of an array.
>
> Yes.
>
> >   * Do we need to add a type-trait for this?
>
> The more interesting question is: What happens if I attempt to define a
> variable of such class type on the stack or globally (at namespace scope)?
> What happens if I call  new MyType   for it?

I'd make unbound aggregates be abstract, so they can't be instantiated by
themselves.

I would also propose making them final, so you can't derive from them (final
abstract types are therefore a weird category). But it might make sense to
derive from them, so long as you can't add new non-static members.

> >   * Does an unbound class type need to be considered incomplete (in
> >   general)?
>
> Then you can't have objects of such a type (similar to void). That sounds
> wrong.

More like abstract, see above.

> >   * Should it be restricted to games with malloc, or should we add new and
> >   direct object support?  If the former, then the types involved need to
> >   be POD.  If the latter, then we need to mandate initialization whenever
> >   an unbound class object is allocated or defined.  (An
> >   in-class-definition brace-or-equal initializer as a last resort is OK.)

> If you want a C++ approach to the underlying problem that these "unbound
> class types" try to solve, you should probably start from scratch in the
> design space.  If it turns out we can usefully extend the C99 syntax, fine,
> but requiring use of "malloc" is certainly not the way to go for C++.

At the very least, you should add wording that aggregates with unbound members
have their constructors deleted if the unbound member has a non-trivial
constructor (and the same for the destructor). Clearly, the trivial copy
constructor, trivial move constructor and assignment operators must be
deleted. Only a user-provided set of copy functions can work.

I don't see how to make unbound types work with operator new, not with major
new syntax. Somehow, the size parameter would need to be passed to both
operator new and the constructor.

This is better solved by having simple wrappers:

template <typename Tail>
struct Unbound : Base
{
 size_t count;
 Tail tail[0];

 Unbound() = delete;
 ~Unbound()
 {
  while (count--)
   tail[count + 1].~Tail();
 }
 Unbound(const Unbound &other)
 {
  if (count != other.count)
   throw std::bad_unbound();
  for (size_t i = 0; i < count; ++i)
   tail[i] = other.tail[i];
 }

 template <typename... Args>
 static Unbound *create(size_t count, Args && ...args)
 {
  // making this exception-safe left as exercise for the reader;
  // note: sizeof(Unbound) is calculated as if tail had 1 item
  Unbound *ptr = operator new(sizeof(Unbound) +
   (count - 1)*sizeof(Tail)));
  ptr->count = count;
  while (count--)
   new (ptr->tail + count + 1) Tail(std::forward(args));
 }
};

This should then work:

 Unbound<int> *ptr = Unbound<int>::create(42);
 delete ptr;

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Thu, 09 Jan 2014 22:28:14 +0100
Raw View
On 01/09/2014 09:40 PM, Billy O'Neal wrote:
>>Other than unnamed bit-fields, I thought all members need to be named.
>
> E.g. anonymous structs and unions are in C++11 to my understanding. That is, this is valid:

Anonymous struct are not in C++11, as far as I know, but anonymous unions are.

Thanks for the correction.

> class Foo
> {
>     union
>     {
>         struct
>         {
>             int a; int b;
>         };
>         struct
>         {
>             char var;
>             char example[7];
>         };
>     };
> };
>
> is valid if I'm not mistaken.See e.g. N3797 9.5 [class.union]/5:

That sectioin covers unions only, not structs in general.

Jens

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Thu, 09 Jan 2014 22:40:26 +0100
Raw View
On 01/09/2014 09:55 PM, Thiago Macieira wrote:
> Two solutions to the problem: either require the compiler to leave the unbound
> member last or require the aggregate to be standard layout.

The latter is probably a more severe restriction.

>>>   * The unbounded sub-object must be named.
>>
>> Other than unnamed bit-fields, I thought all members need to be named.
>
> He's probably thinking of anonymous unions.

Ah, yes.

> Is this allowed?
>
> struct X
> {
>  int i;
>  union {
>   double d;
>   char buf[0];
>  };
> };
>
> And, for that matter, is this allowed?
>
> struct X
> {
>  int i;
>  union {
>   double d[0];
>   char buf[0];
>  };
> };

In both cases, "char buf[0]" is not an array of unknown bound
(brackets have to be empty for these); see 8.3.4 dcl.array.

> I don't see how to make unbound types work with operator new, not with major
> new syntax. Somehow, the size parameter would need to be passed to both
> operator new and the constructor.

Well, we also have std::dynarray and discussion about possible
constructor extensions in
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3810.pdf
so maybe there's a possibility to use a common syntax for both
cases.

> This is better solved by having simple wrappers:
>
> template <typename Tail>
> struct Unbound : Base
> {
>  size_t count;

Make that "const"; the count shouldn't change during
the lifetime of the object.

>  Tail tail[0];
>
>  Unbound() = delete;
>  ~Unbound()
>  {
>   while (count--)
>    tail[count + 1].~Tail();
>  }
>  Unbound(const Unbound &other)
>  {
>   if (count != other.count)
>    throw std::bad_unbound();
>   for (size_t i = 0; i < count; ++i)
>    tail[i] = other.tail[i];
>  }
>
>  template <typename... Args>
>  static Unbound *create(size_t count, Args && ...args)
>  {
>   // making this exception-safe left as exercise for the reader;
>   // note: sizeof(Unbound) is calculated as if tail had 1 item

>   Unbound *ptr = operator new(sizeof(Unbound) +
>    (count - 1)*sizeof(Tail)));
>   ptr->count = count;
>   while (count--)
>    new (ptr->tail + count + 1) Tail(std::forward(args));

That looks wrong; you're possibly moving several times from an rvalue
argument inside "args".

I would define a private constructor that initializes "count" and
the "tail", called from the static "create" function.

>  }
> };
>
> This should then work:
>
>  Unbound<int> *ptr = Unbound<int>::create(42);
>  delete ptr;

That doesn't seem to free the right amount of memory; see also
the "sized deallocation" functionality
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html

Thanks,
Jens

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 10 Jan 2014 07:17:47 +0800
Raw View
On 1/10/14 5:28 AM, Jens Maurer wrote:
> On 01/09/2014 09:40 PM, Billy O'Neal wrote:
>>> Other than unnamed bit-fields, I thought all members need to be named.
>> E.g. anonymous structs and unions are in C++11 to my understanding. That is, this is valid:
> Anonymous struct are not in C++11, as far as I know, but anonymous unions are.
>
> Thanks for the correction.

Is there a particular reason we don't have anonymous structs (inside
unions), or was it just too much effort to "port" the C99 specification
semantics over to C++? So few other things are allowed inside unions,
that it would be surprising if the feature conflicted with anything.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 9 Jan 2014 15:32:41 -0800
Raw View
--001a11c2048e921ec804ef92060c
Content-Type: text/plain; charset=ISO-8859-1

On Thu, Jan 9, 2014 at 3:17 PM, David Krauss <potswa@gmail.com> wrote:

> On 1/10/14 5:28 AM, Jens Maurer wrote:
>
>> On 01/09/2014 09:40 PM, Billy O'Neal wrote:
>>
>>> Other than unnamed bit-fields, I thought all members need to be named.
>>>>
>>> E.g. anonymous structs and unions are in C++11 to my understanding. That
>>> is, this is valid:
>>>
>> Anonymous struct are not in C++11, as far as I know, but anonymous unions
>> are.
>>
>> Thanks for the correction.
>>
>
> Is there a particular reason we don't have anonymous structs (inside
> unions), or was it just too much effort to "port" the C99 specification
> semantics over to C++? So few other things are allowed inside unions, that
> it would be surprising if the feature conflicted with anything.


This is a C11 feature, not a C99 feature, so there's not been that much
time for such porting to be considered. The feature adds complexity to
C++'s implicit special member rules and it's constructor mem-initializer
rules, but I agree that there's no fundamental conflict with C++, if the
new features remain suitably restricted (several C++ implementations
already support this).

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c2048e921ec804ef92060c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jan 9, 2014 at 3:17 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On 1/10/14 5:28 AM, Jens M=
aurer wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
On 01/09/2014 09:40 PM, Billy O&#39;Neal wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Other than unnamed bit-fields, I thought all members need to be named.<br>
</blockquote>
E.g. anonymous structs and unions are in C++11 to my understanding. That is=
, this is valid:<br>
</blockquote>
Anonymous struct are not in C++11, as far as I know, but anonymous unions a=
re.<br>
<br>
Thanks for the correction.<br>
</blockquote>
<br></div>
Is there a particular reason we don&#39;t have anonymous structs (inside un=
ions), or was it just too much effort to &quot;port&quot; the C99 specifica=
tion semantics over to C++? So few other things are allowed inside unions, =
that it would be surprising if the feature conflicted with anything.</block=
quote>
<div><br></div><div>This is a C11 feature, not a C99 feature, so there&#39;=
s not been that much time for such porting to be considered. The feature ad=
ds complexity to C++&#39;s implicit special member rules and it&#39;s const=
ructor mem-initializer rules, but I agree that there&#39;s no fundamental c=
onflict with C++, if the new features remain suitably restricted (several C=
++ implementations already support this).</div>
</div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c2048e921ec804ef92060c--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 09 Jan 2014 19:17:04 -0800
Raw View
--nextPart2089101.2H6eiGd6dA
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On quinta-feira, 9 de janeiro de 2014 22:40:26, Jens Maurer wrote:
> In both cases, "char buf[0]" is not an array of unknown bound
> (brackets have to be empty for these); see 8.3.4 dcl.array.

Sorry, I didn't check what the syntax was. We have used both [0] and [] in the
past to do this.

> > This is better solved by having simple wrappers:
> >
> > template <typename Tail>
> > struct Unbound : Base
> > {
> >
> >  size_t count;
>
> Make that "const"; the count shouldn't change during
> the lifetime of the object.

Right, I should. I didn't only so I didn't have to write a private constructor
for the struct in this example.

> >  template <typename... Args>
> >  static Unbound *create(size_t count, Args && ...args)
> >  {
> >
> >   // making this exception-safe left as exercise for the reader;
> >   // note: sizeof(Unbound) is calculated as if tail had 1 item
> >
> >   Unbound *ptr = operator new(sizeof(Unbound) +
> >
> >    (count - 1)*sizeof(Tail)));
> >
> >   ptr->count = count;
> >   while (count--)
> >
> >    new (ptr->tail + count + 1) Tail(std::forward(args));
>
> That looks wrong; you're possibly moving several times from an rvalue
> argument inside "args".
>
> I would define a private constructor that initializes "count" and
> the "tail", called from the static "create" function.

That's the only way I know how to do a perfect forward. Obviously the type's
constructor must not move, which is just a requirement for the type.

> >  }
> >
> > };
> >
> > This should then work:
> >  Unbound<int> *ptr = Unbound<int>::create(42);
> >  delete ptr;
>
> That doesn't seem to free the right amount of memory; see also
> the "sized deallocation" functionality
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html

I don't think it's necessary. I'm certain that the right amount of memory gets
freed. If Unbound::operator delete() doesn't exist, the above delete will call
the enclosing scope's operator delete(), which matches the operator new() call
we placed in Unbound::create().

The sized deallocation functionality is not necessary.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--nextPart2089101.2H6eiGd6dA
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBSz2ZMM/XwBW70U1gRAtR5AKCyvb2irMSBI2JwLPYsLpG/WQeSSwCeNbGR
bYwhUMC4LnfnU7a5pWg3Lpw=
=ibTa
-----END PGP SIGNATURE-----

--nextPart2089101.2H6eiGd6dA--


.