Topic: Static constructors/destructors in C++


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Fri, 22 Jul 2016 08:52:16 -0700 (PDT)
Raw View
------=_Part_473_1415857158.1469202736493
Content-Type: multipart/alternative;
 boundary="----=_Part_474_1542091053.1469202736493"

------=_Part_474_1542091053.1469202736493
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



For over years I heard interview questions like: =E2=80=9Cdoes C++ have a s=
tatic=20
constructor=E2=80=9D or =E2=80=9Cwhat static constructor do=E2=80=9D. Of co=
urse there is no such=20
type of constructors in C++. However it would be extremely useful=E2=80=A6

=20

My proposition is to provide a static constructor and destructor in C++.=20
The static constructor will be executed once before main() function and=20
static destructor just after it. So it works in the same manner as for a=20
global object with one difference: there is no associated object. Static=20
ctor/dtor is called once, even if object was never created. It generally=20
behave as usual static function. Therefore you cannot use this pointer=20
within such ctor/dtor.

=20

I see a numerous purposes for this thing. The most important are:


   - Easier class registration/deregistration
   - New mechanism for singleton implementation
   - Class code can be now executed w/o creating object and w/o external=20
   call.
   - And the best one: Including/Excluding h/cpp file into application=20
   allows enabling/disabling functionality without using preprocessor.
  =20
=20

let=E2=80=99s consider a following example:

=20

class MyPlugin : public Plugin {

  private:

    Plugin &getPluginInstance() {

      static MyPlugin myPlugin;

      return myPlugin;

    }

  public:

    static MyPlugin() {=20

      Plugins::registerPlugin(getPluginInstance());

    }

    static ~MyPlugin() {

      Plugins::unregisterPlugin(getPluginInstance());

    }

};


Here are the rules:


   - Static constructors of different classes are executed one by one in=20
   the same order as corresponding classes were defined.
   - Static constructors are always executed before software entry point=20
   (the main() function) and always before constructors of all global=20
   objects.
   - Static destructors are executed one by one in reverse order to the=20
   order of corresponding classes definition.
   - Static destructors are always executed after software entry point and=
=20
   always after constructors of all global objects.
   - If both base and derived class have a static constructor, first is=20
   called a static constructor of base class
   - If both base and derived class have a static destructor, first is=20
   called a static destructor of derived class
   - static constructor and destructor have no parameters
   - static constructor and destructor behaves as usual static function
   - this pointer cannot be used within static constructor nor destructor
   - I suggest to disallow manual call of static ctor/dtor. It should be=20
   autonomous mechanism for specific purposes only. Callable functionality=
=20
   should be always provided as named functions or overloaded operators=20
   according to its purpose.
  =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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/99627390-80d0-4ff4-be72-cdf0232e8ab9%40isocpp.or=
g.

------=_Part_474_1542091053.1469202736493
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><p class=3D"MsoNormal"><span lang=3D"EN-US">For over
years I heard interview questions like: =E2=80=9Cdoes C++ have a static con=
structor=E2=80=9D or
=E2=80=9Cwhat static constructor do=E2=80=9D. Of course there is no such ty=
pe of constructors
in C++. However it would be extremely useful=E2=80=A6<o:p></o:p></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">My
proposition is to provide a static constructor and destructor in C++. The
static constructor will be executed once before <font face=3D"courier new, =
monospace">main()</font> function and static destructor
just after it. So it works in the same manner as for a global object with o=
ne
difference: there is no associated object. Static ctor/dtor is called once,=
 even
if object was never created. It generally behave as usual static function.
Therefore you cannot use <font face=3D"courier new, monospace">this</font>=
=C2=A0pointer within such ctor/dtor.<o:p></o:p></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">I see a
numerous purposes for this thing. The most important are:<o:p></o:p></span>=
</p>

<p class=3D"MsoNormal"></p><ul><li>Easier class
registration/deregistration<br></li><li>New
mechanism for singleton implementation<br></li><li>Class code
can be now executed w/o creating object and w/o external call.<br></li><li>=
And the
best one: Including/Excluding h/cpp file into application allows enabling/d=
isabling
functionality without using preprocessor.<br></li></ul><p></p>







<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">let=E2=80=99s
consider a following example:<o:p></o:p></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">class MyPlugin
: public Plugin {<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 private:<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 Plugin &amp;getPluginInstance() {<o:p></o:p></fon=
t></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static MyPlugin myPlugin;<o:p></o:p><=
/font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return myPlugin;<o:p></o:p></font></s=
pan></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 public:<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static MyPlugin() { <o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::registerPlugin(getPluginInstance(=
));<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static ~MyPlugin() {<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::unregisterPlugin(getPluginInstanc=
e());<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">};</font><o:p></o:p></span></p>

<p class=3D"MsoNormal"><br></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">Here are
the rules:<o:p></o:p></span></p>

<p class=3D"MsoNormal"></p><ul><li>Static
constructors of different classes are executed one by one in the same order=
 as
corresponding classes were defined.<br></li><li>Static
constructors are always executed before software entry point (the <font fac=
e=3D"courier new, monospace">main()</font> function) and always before cons=
tructors of all global objects.<br></li><li>Static
destructors are executed one by one in reverse order to the order of
corresponding classes definition.<br></li><li>Static
destructors are always executed after software entry point and always after
constructors of all global objects.<br></li><li>If both
base and derived class have a static constructor, first is called a static
constructor of base class<br></li><li>If both
base and derived class have a static destructor, first is called a static
destructor of derived class<br></li><li>static
constructor and destructor have no parameters<br></li><li>static
constructor and destructor behaves as usual static function<br></li><li><fo=
nt face=3D"courier new, monospace">this</font>
pointer cannot be used within static constructor nor destructor<br></li><li=
>I suggest
to disallow manual call of static ctor/dtor. It should be autonomous mechan=
ism
for specific purposes only. Callable functionality should be always provide=
d as
named functions or overloaded operators according to its purpose.<br></li><=
/ul><p></p>

















</div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/99627390-80d0-4ff4-be72-cdf0232e8ab9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/99627390-80d0-4ff4-be72-cdf0232e8ab9=
%40isocpp.org</a>.<br />

------=_Part_474_1542091053.1469202736493--

------=_Part_473_1415857158.1469202736493--

.


Author: szollosi.lorand@gmail.com
Date: Fri, 22 Jul 2016 09:04:29 -0700 (PDT)
Raw View
------=_Part_574_2097185766.1469203469383
Content-Type: multipart/alternative;
 boundary="----=_Part_575_756704875.1469203469383"

------=_Part_575_756704875.1469203469383
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

How is it different from a *static bool* member variable that's initialized=
=20
by the return value of your constructor? This additionally helps you by=20
allowing return value: this is needed as you couldn't *throw* from a static=
=20
constructor to signal errors. If you wanted a destructor as well, then have=
=20
a *static struct StaticMyPlugin { StaticMyPlugin() { ... }=20
~StaticMyPlugin() { ... } } staticMyPlugin; *This is almost the syntax you=
=20
wanted.

Regards,
-lorro

2016. j=C3=BAlius 22., p=C3=A9ntek 17:52:17 UTC+2 id=C5=91pontban Mariusz M=
oczala a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> For over years I heard interview questions like: =E2=80=9Cdoes C++ have a=
 static=20
> constructor=E2=80=9D or =E2=80=9Cwhat static constructor do=E2=80=9D. Of =
course there is no such=20
> type of constructors in C++. However it would be extremely useful=E2=80=
=A6
>
> =20
>
> My proposition is to provide a static constructor and destructor in C++.=
=20
> The static constructor will be executed once before main() function and=
=20
> static destructor just after it. So it works in the same manner as for a=
=20
> global object with one difference: there is no associated object. Static=
=20
> ctor/dtor is called once, even if object was never created. It generally=
=20
> behave as usual static function. Therefore you cannot use this pointer=20
> within such ctor/dtor.
>
> =20
>
> I see a numerous purposes for this thing. The most important are:
>
>
>    - Easier class registration/deregistration
>    - New mechanism for singleton implementation
>    - Class code can be now executed w/o creating object and w/o external=
=20
>    call.
>    - And the best one: Including/Excluding h/cpp file into application=20
>    allows enabling/disabling functionality without using preprocessor.
>   =20
> =20
>
> let=E2=80=99s consider a following example:
>
> =20
>
> class MyPlugin : public Plugin {
>
>   private:
>
>     Plugin &getPluginInstance() {
>
>       static MyPlugin myPlugin;
>
>       return myPlugin;
>
>     }
>
>   public:
>
>     static MyPlugin() {=20
>
>       Plugins::registerPlugin(getPluginInstance());
>
>     }
>
>     static ~MyPlugin() {
>
>       Plugins::unregisterPlugin(getPluginInstance());
>
>     }
>
> };
>
>
> Here are the rules:
>
>
>    - Static constructors of different classes are executed one by one in=
=20
>    the same order as corresponding classes were defined.
>    - Static constructors are always executed before software entry point=
=20
>    (the main() function) and always before constructors of all global=20
>    objects.
>    - Static destructors are executed one by one in reverse order to the=
=20
>    order of corresponding classes definition.
>    - Static destructors are always executed after software entry point=20
>    and always after constructors of all global objects.
>    - If both base and derived class have a static constructor, first is=
=20
>    called a static constructor of base class
>    - If both base and derived class have a static destructor, first is=20
>    called a static destructor of derived class
>    - static constructor and destructor have no parameters
>    - static constructor and destructor behaves as usual static function
>    - this pointer cannot be used within static constructor nor destructor
>    - I suggest to disallow manual call of static ctor/dtor. It should be=
=20
>    autonomous mechanism for specific purposes only. Callable functionalit=
y=20
>    should be always provided as named functions or overloaded operators=
=20
>    according to its purpose.
>   =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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/fae9f871-7738-41c3-b058-9c7ae6efd55d%40isocpp.or=
g.

------=_Part_575_756704875.1469203469383
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>How is it different from a <i>static bool</i> m=
ember variable that&#39;s initialized by the return value of your construct=
or? This additionally helps you by allowing return value: this is needed as=
 you couldn&#39;t <i>throw</i> from a static constructor to signal errors. =
If you wanted a destructor as well, then have a <i>static struct StaticMyPl=
ugin { StaticMyPlugin() { ... } ~StaticMyPlugin() { ... } } staticMyPlugin;=
 </i>This is almost the syntax you wanted.<br><i><br></i>Regards,<i><br></i=
>-lorro<br><br>2016. j=C3=BAlius 22., p=C3=A9ntek 17:52:17 UTC+2 id=C5=91po=
ntban Mariusz Moczala a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><p class=3D"MsoNormal"><span lang=
=3D"EN-US">For over
years I heard interview questions like: =E2=80=9Cdoes C++ have a static con=
structor=E2=80=9D or
=E2=80=9Cwhat static constructor do=E2=80=9D. Of course there is no such ty=
pe of constructors
in C++. However it would be extremely useful=E2=80=A6</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">My
proposition is to provide a static constructor and destructor in C++. The
static constructor will be executed once before <font face=3D"courier new, =
monospace">main()</font> function and static destructor
just after it. So it works in the same manner as for a global object with o=
ne
difference: there is no associated object. Static ctor/dtor is called once,=
 even
if object was never created. It generally behave as usual static function.
Therefore you cannot use <font face=3D"courier new, monospace">this</font>=
=C2=A0pointer within such ctor/dtor.</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">I see a
numerous purposes for this thing. The most important are:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Easier class
registration/deregistration<br></li><li>New
mechanism for singleton implementation<br></li><li>Class code
can be now executed w/o creating object and w/o external call.<br></li><li>=
And the
best one: Including/Excluding h/cpp file into application allows enabling/d=
isabling
functionality without using preprocessor.<br></li></ul><p></p>







<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">let=E2=80=99s
consider a following example:</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">class MyPlugin
: public Plugin {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 private:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 Plugin &amp;getPluginInstance() {</font></span></=
p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static MyPlugin myPlugin;</font></spa=
n></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return myPlugin;</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 public:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static MyPlugin() { </font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::registerPlugin(<wbr>getPluginInst=
ance());</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static ~MyPlugin() {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::unregisterPlugin(<wbr>getPluginIn=
stance());</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">};</font></span></p>

<p class=3D"MsoNormal"><br></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">Here are
the rules:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Static
constructors of different classes are executed one by one in the same order=
 as
corresponding classes were defined.<br></li><li>Static
constructors are always executed before software entry point (the <font fac=
e=3D"courier new, monospace">main()</font> function) and always before cons=
tructors of all global objects.<br></li><li>Static
destructors are executed one by one in reverse order to the order of
corresponding classes definition.<br></li><li>Static
destructors are always executed after software entry point and always after
constructors of all global objects.<br></li><li>If both
base and derived class have a static constructor, first is called a static
constructor of base class<br></li><li>If both
base and derived class have a static destructor, first is called a static
destructor of derived class<br></li><li>static
constructor and destructor have no parameters<br></li><li>static
constructor and destructor behaves as usual static function<br></li><li><fo=
nt face=3D"courier new, monospace">this</font>
pointer cannot be used within static constructor nor destructor<br></li><li=
>I suggest
to disallow manual call of static ctor/dtor. It should be autonomous mechan=
ism
for specific purposes only. Callable functionality should be always provide=
d as
named functions or overloaded operators according to its purpose.<br></li><=
/ul><p></p>

















</div></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fae9f871-7738-41c3-b058-9c7ae6efd55d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fae9f871-7738-41c3-b058-9c7ae6efd55d=
%40isocpp.org</a>.<br />

------=_Part_575_756704875.1469203469383--

------=_Part_574_2097185766.1469203469383--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 22 Jul 2016 09:05:25 -0700
Raw View
On sexta-feira, 22 de julho de 2016 08:52:16 PDT Mariusz Moczala wrote:
> For over years I heard interview questions like: =E2=80=9Cdoes C++ have a=
 static
> constructor=E2=80=9D or =E2=80=9Cwhat static constructor do=E2=80=9D. Of =
course there is no such
> type of constructors in C++. However it would be extremely useful=E2=80=
=A6

What you described below does exist and has been part of the language since=
=20
C++98, except that it requires an object. I don't see the committee adding=
=20
another syntax to do the same thing that is already possible.

> I see a numerous purposes for this thing. The most important are:
>=20
>=20
>    - Easier class registration/deregistration
>    - New mechanism for singleton implementation
>    - Class code can be now executed w/o creating object and w/o external
>    call.

Please explain how this is superior to the existing alternative.

>    - And the best one: Including/Excluding h/cpp file into application
>    allows enabling/disabling functionality without using preprocessor.

And please explain how this would happen. I don't see it.

> Here are the rules:
>=20
>    - Static constructors of different classes are executed one by one in
>    the same order as corresponding classes were defined.

Classes are not defined in any order. This point must either be completely=
=20
gone, saying that the registration is done in any arbitrary order, or you m=
ust=20
provide an explanation of how the compiler and linker in a project with 100=
0=20
translation units would know what the order is.

And please think of the dynamic linker when there are 50 libraries loaded.

And then consider what happens when you load plugins simultaneously from tw=
o=20
different threads.

>    - Static constructors are always executed before software entry point
>    (the main() function) and always before constructors of all global
>    objects.
>    - Static destructors are executed one by one in reverse order to the
>    order of corresponding classes definition.
>    - Static destructors are always executed after software entry point an=
d
>    always after constructors of all global objects.

Considering the lack of ordering of the point above, I don't see how this=
=20
would work. Is running something before the other constructors the most=20
important feature?

>    - If both base and derived class have a static constructor, first is
>    called a static constructor of base class
>    - If both base and derived class have a static destructor, first is
>    called a static destructor of derived class

Same ordering problem as before, now more difficult: this requires that the=
=20
linker figure out the inheritance graph.

>    - static constructor and destructor have no parameters
>    - static constructor and destructor behaves as usual static function
>    - this pointer cannot be used within static constructor nor destructor
>    - I suggest to disallow manual call of static ctor/dtor. It should be
>    autonomous mechanism for specific purposes only. Callable functionalit=
y
>    should be always provided as named functions or overloaded operators
>    according to its purpose.


--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3406468.UUnzNiV1us%40tjmaciei-mobl1.

.


Author: Patrice Roy <patricer@gmail.com>
Date: Fri, 22 Jul 2016 12:08:01 -0400
Raw View
--001a114e52f89278ef05383ba33d
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

What do you mean by =C2=ABreturn value of your constructor=C2=BB?

2016-07-22 12:04 GMT-04:00 <szollosi.lorand@gmail.com>:

> Hi,
>
> How is it different from a *static bool* member variable that's
> initialized by the return value of your constructor? This additionally
> helps you by allowing return value: this is needed as you couldn't *throw=
*
> from a static constructor to signal errors. If you wanted a destructor as
> well, then have a *static struct StaticMyPlugin { StaticMyPlugin() { ...
> } ~StaticMyPlugin() { ... } } staticMyPlugin; *This is almost the syntax
> you wanted.
>
> Regards,
> -lorro
>
>
> 2016. j=C3=BAlius 22., p=C3=A9ntek 17:52:17 UTC+2 id=C5=91pontban Mariusz=
 Moczala a
> k=C3=B6vetkez=C5=91t =C3=ADrta:
>>
>> For over years I heard interview questions like: =E2=80=9Cdoes C++ have =
a static
>> constructor=E2=80=9D or =E2=80=9Cwhat static constructor do=E2=80=9D. Of=
 course there is no such
>> type of constructors in C++. However it would be extremely useful=E2=80=
=A6
>>
>>
>>
>> My proposition is to provide a static constructor and destructor in C++.
>> The static constructor will be executed once before main() function and
>> static destructor just after it. So it works in the same manner as for a
>> global object with one difference: there is no associated object. Static
>> ctor/dtor is called once, even if object was never created. It generally
>> behave as usual static function. Therefore you cannot use this pointer
>> within such ctor/dtor.
>>
>>
>>
>> I see a numerous purposes for this thing. The most important are:
>>
>>
>>    - Easier class registration/deregistration
>>    - New mechanism for singleton implementation
>>    - Class code can be now executed w/o creating object and w/o external
>>    call.
>>    - And the best one: Including/Excluding h/cpp file into application
>>    allows enabling/disabling functionality without using preprocessor.
>>
>>
>>
>> let=E2=80=99s consider a following example:
>>
>>
>>
>> class MyPlugin : public Plugin {
>>
>>   private:
>>
>>     Plugin &getPluginInstance() {
>>
>>       static MyPlugin myPlugin;
>>
>>       return myPlugin;
>>
>>     }
>>
>>   public:
>>
>>     static MyPlugin() {
>>
>>       Plugins::registerPlugin(getPluginInstance());
>>
>>     }
>>
>>     static ~MyPlugin() {
>>
>>       Plugins::unregisterPlugin(getPluginInstance());
>>
>>     }
>>
>> };
>>
>>
>> Here are the rules:
>>
>>
>>    - Static constructors of different classes are executed one by one in
>>    the same order as corresponding classes were defined.
>>    - Static constructors are always executed before software entry point
>>    (the main() function) and always before constructors of all global
>>    objects.
>>    - Static destructors are executed one by one in reverse order to the
>>    order of corresponding classes definition.
>>    - Static destructors are always executed after software entry point
>>    and always after constructors of all global objects.
>>    - If both base and derived class have a static constructor, first is
>>    called a static constructor of base class
>>    - If both base and derived class have a static destructor, first is
>>    called a static destructor of derived class
>>    - static constructor and destructor have no parameters
>>    - static constructor and destructor behaves as usual static function
>>    - this pointer cannot be used within static constructor nor destructo=
r
>>    - I suggest to disallow manual call of static ctor/dtor. It should be
>>    autonomous mechanism for specific purposes only. Callable functionali=
ty
>>    should be always provided as named functions or overloaded operators
>>    according to its purpose.
>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fae9f871-773=
8-41c3-b058-9c7ae6efd55d%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fae9f871-77=
38-41c3-b058-9c7ae6efd55d%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAKiZDp0mAVC7WiTyJHrWy%3Dsy%2BNHbHSqzqZk0-uXnEuM=
8xV%3DVCQ%40mail.gmail.com.

--001a114e52f89278ef05383ba33d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">What do you mean by =C2=ABreturn value of your constructor=
=C2=BB?<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2016-07-22 12:04 GMT-04:00  <span dir=3D"ltr">&lt;<a href=3D"mailto:szollos=
i.lorand@gmail.com" target=3D"_blank">szollosi.lorand@gmail.com</a>&gt;</sp=
an>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<br><br>How is i=
t different from a <i>static bool</i> member variable that&#39;s initialize=
d by the return value of your constructor? This additionally helps you by a=
llowing return value: this is needed as you couldn&#39;t <i>throw</i> from =
a static constructor to signal errors. If you wanted a destructor as well, =
then have a <i>static struct StaticMyPlugin { StaticMyPlugin() { ... } ~Sta=
ticMyPlugin() { ... } } staticMyPlugin; </i>This is almost the syntax you w=
anted.<br><i><br></i>Regards,<i><br></i>-lorro<div><div class=3D"h5"><br><b=
r>2016. j=C3=BAlius 22., p=C3=A9ntek 17:52:17 UTC+2 id=C5=91pontban Mariusz=
 Moczala a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><p class=3D"MsoNormal"><span lang=3D"EN-US">For ove=
r
years I heard interview questions like: =E2=80=9Cdoes C++ have a static con=
structor=E2=80=9D or
=E2=80=9Cwhat static constructor do=E2=80=9D. Of course there is no such ty=
pe of constructors
in C++. However it would be extremely useful=E2=80=A6</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">My
proposition is to provide a static constructor and destructor in C++. The
static constructor will be executed once before <font face=3D"courier new, =
monospace">main()</font> function and static destructor
just after it. So it works in the same manner as for a global object with o=
ne
difference: there is no associated object. Static ctor/dtor is called once,=
 even
if object was never created. It generally behave as usual static function.
Therefore you cannot use <font face=3D"courier new, monospace">this</font>=
=C2=A0pointer within such ctor/dtor.</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">I see a
numerous purposes for this thing. The most important are:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Easier class
registration/deregistration<br></li><li>New
mechanism for singleton implementation<br></li><li>Class code
can be now executed w/o creating object and w/o external call.<br></li><li>=
And the
best one: Including/Excluding h/cpp file into application allows enabling/d=
isabling
functionality without using preprocessor.<br></li></ul><p></p>







<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">let=E2=80=99s
consider a following example:</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">class MyPlugin
: public Plugin {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 private:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 Plugin &amp;getPluginInstance() {</font></span></=
p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static MyPlugin myPlugin;</font></spa=
n></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return myPlugin;</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 public:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static MyPlugin() { </font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::registerPlugin(getPluginInstance(=
));</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static ~MyPlugin() {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::unregisterPlugin(getPluginInstanc=
e());</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">};</font></span></p>

<p class=3D"MsoNormal"><br></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">Here are
the rules:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Static
constructors of different classes are executed one by one in the same order=
 as
corresponding classes were defined.<br></li><li>Static
constructors are always executed before software entry point (the <font fac=
e=3D"courier new, monospace">main()</font> function) and always before cons=
tructors of all global objects.<br></li><li>Static
destructors are executed one by one in reverse order to the order of
corresponding classes definition.<br></li><li>Static
destructors are always executed after software entry point and always after
constructors of all global objects.<br></li><li>If both
base and derived class have a static constructor, first is called a static
constructor of base class<br></li><li>If both
base and derived class have a static destructor, first is called a static
destructor of derived class<br></li><li>static
constructor and destructor have no parameters<br></li><li>static
constructor and destructor behaves as usual static function<br></li><li><fo=
nt face=3D"courier new, monospace">this</font>
pointer cannot be used within static constructor nor destructor<br></li><li=
>I suggest
to disallow manual call of static ctor/dtor. It should be autonomous mechan=
ism
for specific purposes only. Callable functionality should be always provide=
d as
named functions or overloaded operators according to its purpose.<br></li><=
/ul><p></p>

















</div></blockquote></div></div></div><div><div class=3D"h5">

<p></p>

-- <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+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fae9f871-7738-41c3-b058-9c7ae6efd55d%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fae9f871-7738-=
41c3-b058-9c7ae6efd55d%40isocpp.org</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAKiZDp0mAVC7WiTyJHrWy%3Dsy%2BNHbHSqz=
qZk0-uXnEuM8xV%3DVCQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKiZDp0mAV=
C7WiTyJHrWy%3Dsy%2BNHbHSqzqZk0-uXnEuM8xV%3DVCQ%40mail.gmail.com</a>.<br />

--001a114e52f89278ef05383ba33d--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Jul 2016 09:08:17 -0700 (PDT)
Raw View
------=_Part_258_1871648792.1469203697292
Content-Type: multipart/alternative;
 boundary="----=_Part_259_367101836.1469203697292"

------=_Part_259_367101836.1469203697292
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, July 22, 2016 at 11:52:17 AM UTC-4, Mariusz Moczala wrote:
>
> For over years I heard interview questions like: =E2=80=9Cdoes C++ have a=
 static=20
> constructor=E2=80=9D or =E2=80=9Cwhat static constructor do=E2=80=9D. Of =
course there is no such=20
> type of constructors in C++. However it would be extremely useful=E2=80=
=A6
>
> =20
>
> My proposition is to provide a static constructor and destructor in C++.=
=20
> The static constructor will be executed once before main() function and=
=20
> static destructor just after it. So it works in the same manner as for a=
=20
> global object with one difference: there is no associated object. Static=
=20
> ctor/dtor is called once, even if object was never created. It generally=
=20
> behave as usual static function. Therefore you cannot use this pointer=20
> within such ctor/dtor.
>
> =20
>
> I see a numerous purposes for this thing. The most important are:
>
>
>    - Easier class registration/deregistration
>    - New mechanism for singleton implementation
>   =20
> 1) What's wrong with the current singleton implementations?

2) Why should we add a feature for something that's widely considered to be=
=20
a bad idea in the first place?

>
>    - Class code can be now executed w/o creating object and w/o external=
=20
>    call.
>   =20
> Why is it important that we have a constructor/destructor pair without an=
=20
object? Are we running out of objects?

>
>    - And the best one: Including/Excluding h/cpp file into application=20
>    allows enabling/disabling functionality without using preprocessor.
>   =20
> In what way? Or more to the point, in what way would this do what you=20
want that couldn't be done with an actual object?

let=E2=80=99s consider a following example:

=20
>
> class MyPlugin : public Plugin {
>
>   private:
>
>     Plugin &getPluginInstance() {
>
>       static MyPlugin myPlugin;
>
>       return myPlugin;
>
>     }
>
>   public:
>
>     static MyPlugin() {=20
>
>       Plugins::registerPlugin(getPluginInstance());
>
>     }
>
>     static ~MyPlugin() {
>
>       Plugins::unregisterPlugin(getPluginInstance());
>
>     }
>
> };
>
>
> Here are the rules:
>
>
>    - Static constructors of different classes are executed one by one in=
=20
>    the same order as corresponding classes were defined.
>   =20
> That's great. What order is that, exactly?

If definitions were actually *ordered*, we wouldn't have a problem with=20
global/static object initialization ordering.

>
>    - Static constructors are always executed before software entry point=
=20
>    (the main() function) and always before constructors of all global=20
>    objects.
>    - Static destructors are executed one by one in reverse order to the=
=20
>    order of corresponding classes definition.
>    - Static destructors are always executed after software entry point=20
>    and always after constructors of all global objects.
>    - If both base and derived class have a static constructor, first is=
=20
>    called a static constructor of base class
>    - If both base and derived class have a static destructor, first is=20
>    called a static destructor of derived class
>    - static constructor and destructor have no parameters
>    - static constructor and destructor behaves as usual static function
>    - this pointer cannot be used within static constructor nor destructor
>   =20
> Your example constructor used `this` just fine. How else could it call th=
e=20
non-static `getPluginInstance` function? Or did you mean for that function=
=20
to be static too?

>
>    - I suggest to disallow manual call of static ctor/dtor. It should be=
=20
>    autonomous mechanism for specific purposes only. Callable functionalit=
y=20
>    should be always provided as named functions or overloaded operators=
=20
>    according to its purpose.
>   =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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/fe945c56-36c9-4d07-822d-6c6ee9d2cea4%40isocpp.or=
g.

------=_Part_259_367101836.1469203697292
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, July 22, 2016 at 11:52:17 AM UTC-4, Mariusz Moc=
zala wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><p=
 class=3D"MsoNormal"><span lang=3D"EN-US">For over
years I heard interview questions like: =E2=80=9Cdoes C++ have a static con=
structor=E2=80=9D or
=E2=80=9Cwhat static constructor do=E2=80=9D. Of course there is no such ty=
pe of constructors
in C++. However it would be extremely useful=E2=80=A6</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">My
proposition is to provide a static constructor and destructor in C++. The
static constructor will be executed once before <font face=3D"courier new, =
monospace">main()</font> function and static destructor
just after it. So it works in the same manner as for a global object with o=
ne
difference: there is no associated object. Static ctor/dtor is called once,=
 even
if object was never created. It generally behave as usual static function.
Therefore you cannot use <font face=3D"courier new, monospace">this</font>=
=C2=A0pointer within such ctor/dtor.</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">I see a
numerous purposes for this thing. The most important are:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Easier class
registration/deregistration<br></li><li>New
mechanism for singleton implementation<br></li></ul></div></blockquote><div=
>1) What&#39;s wrong with the current singleton implementations?<br><br>2) =
Why should we add a feature for something that&#39;s widely considered to b=
e a bad idea in the first place?<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><ul><li>Class code
can be now executed w/o creating object and w/o external call.<br></li></ul=
></div></blockquote><div>Why is it important that we have a constructor/des=
tructor pair without an object? Are we running out of objects?<br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><ul><li>And the
best one: Including/Excluding h/cpp file into application allows enabling/d=
isabling
functionality without using preprocessor.<br></li></ul></div></blockquote><=
div>In what way? <span lang=3D"EN-US">Or more to the point, in what way wou=
ld this do what you want that couldn&#39;t be done with an actual object?<b=
r><br></span><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1=
px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><spa=
n lang=3D"EN-US">let=E2=80=99s
consider a following example:</span></blockquote></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr">

<p class=3D"MsoNormal"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">class MyPlugin
: public Plugin {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 private:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 Plugin &amp;getPluginInstance() {</font></span></=
p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static MyPlugin myPlugin;</font></spa=
n></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return myPlugin;</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 public:</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static MyPlugin() { </font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::registerPlugin(<wbr>getPluginInst=
ance());</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 static ~MyPlugin() {</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0=C2=A0Plugins::unregisterPlugin(<wbr>getPluginIn=
stance());</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">=C2=A0=C2=A0=C2=A0 }</font></span></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US"><font face=3D"courier new, mono=
space">};</font></span></p>

<p class=3D"MsoNormal"><br></p>

<p class=3D"MsoNormal"><span lang=3D"EN-US">Here are
the rules:</span></p>

<p class=3D"MsoNormal"></p><ul><li>Static
constructors of different classes are executed one by one in the same order=
 as
corresponding classes were defined.<br></li></ul></div></blockquote><div>Th=
at&#39;s great. What order is that, exactly?<br><br>If definitions were act=
ually <i>ordered</i>, we wouldn&#39;t have a problem with global/static obj=
ect initialization ordering.<br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><ul><li>Static
constructors are always executed before software entry point (the <font fac=
e=3D"courier new, monospace">main()</font> function) and always before cons=
tructors of all global objects.<br></li><li>Static
destructors are executed one by one in reverse order to the order of
corresponding classes definition.<br></li><li>Static
destructors are always executed after software entry point and always after
constructors of all global objects.<br></li><li>If both
base and derived class have a static constructor, first is called a static
constructor of base class<br></li><li>If both
base and derived class have a static destructor, first is called a static
destructor of derived class<br></li><li>static
constructor and destructor have no parameters<br></li><li>static
constructor and destructor behaves as usual static function<br></li><li><fo=
nt face=3D"courier new, monospace">this</font>
pointer cannot be used within static constructor nor destructor<br></li></u=
l></div></blockquote><div>Your example constructor used `this` just fine. H=
ow else could it call the non-static `getPluginInstance` function? Or did y=
ou mean for that function to be static too?<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><ul><li>I suggest
to disallow manual call of static ctor/dtor. It should be autonomous mechan=
ism
for specific purposes only. Callable functionality should be always provide=
d as
named functions or overloaded operators according to its purpose.<br></li><=
/ul><p></p>

















</div></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fe945c56-36c9-4d07-822d-6c6ee9d2cea4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fe945c56-36c9-4d07-822d-6c6ee9d2cea4=
%40isocpp.org</a>.<br />

------=_Part_259_367101836.1469203697292--

------=_Part_258_1871648792.1469203697292--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Fri, 22 Jul 2016 10:11:02 -0700 (PDT)
Raw View
------=_Part_659_855157567.1469207462446
Content-Type: multipart/alternative;
 boundary="----=_Part_660_186068126.1469207462446"

------=_Part_660_186068126.1469207462446
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Thank you very much for all comments. Please have a look at the simplified=
=20
code once again:

class MyPlugin : public Plugin {
  public:
    static MyPlugin() {
      static MyPlugin myPlugin;
      Plugins::registerPlugin(myPlugin);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(*this);
    }
};

This is a complete, executable code. Previously I have forgotten static=20
keyword for getPluginInstance function. Thank you for pointing this out!

Let=E2=80=99s consider the plug-in registration. Currently in C++ to execut=
e class=20
code, you need to at least create an object to execute default=20
constructor=E2=80=99s code. You can also call a static function. However to=
=20
register a new plug-in, programmer have to write some code.

With static constructors you can just add a cpp / obj / lib file into your=
=20
project. Or just include a header file with above class in any source file.=
=20
The static constructor of MyPlugin class will create a static object, so=20
you do not need to do this manually in a cpp file. The static constructor=
=20
also calls Plugins::registerPlugin on the object, so it is also=20
automatically registered. Just by a including header file.

After reading your comments I found that there is actually no need for=20
static destructor. As you can create a static object in static constructor,=
=20
then regular destructor can perform a deregistration. According to this,=20
there is no longer need to consider the execution order.

Briefly, the linker should now operate this way:

   - Call static constructors form all translation units and libs
   - Call constructors for global variables (as usual)
   - Call main() function (as usual)
   - Call destructors for global variables (as usual)

Please correct me if I am missing something here: If lib file have a static=
=20
constructor providing plugin registration, it will be automatically=20
executed and there is no longer need to provide a header file associated=20
with the lib to use it in a project.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/dc2fc694-5dba-44c3-9451-5b0f98880878%40isocpp.or=
g.

------=_Part_660_186068126.1469207462446
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thank you very much for all comments. Please have a l=
ook at the simplified code once again:</div><div><br></div><font face=3D"co=
urier new, monospace">class MyPlugin : public Plugin {<br>=C2=A0 public:<br=
>=C2=A0 =C2=A0 static MyPlugin() {<br></font><span style=3D"font-family: &q=
uot;courier new&quot;, monospace;">=C2=A0 =C2=A0 =C2=A0 static MyPlugin myP=
lugin;</span><br style=3D"font-family: &quot;courier new&quot;, monospace;"=
><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 Plugins::r=
egisterPlugin(</font><span style=3D"font-family: &quot;courier new&quot;, m=
onospace;">myPlugin</span><font face=3D"courier new, monospace">);<br>=C2=
=A0 =C2=A0 }<br>=C2=A0 =C2=A0 ~MyPlugin() {<br>=C2=A0 =C2=A0 =C2=A0 Plugins=
::unregisterPlugin(*this);<br>=C2=A0 =C2=A0 }<br>};</font><div><br></div><d=
iv>This is a complete, executable code. Previously I have forgotten static =
keyword for getPluginInstance function. Thank you for pointing this out!</d=
iv><div><br></div><div>Let=E2=80=99s consider the plug-in registration. Cur=
rently in C++ to execute class code, you need to at least create an object =
to execute default constructor=E2=80=99s code. You can also call a static f=
unction. However to register a new plug-in, programmer have to write some c=
ode.</div><div><br></div><div>With static constructors you can just add a c=
pp / obj / lib file into your project. Or just include a header file with a=
bove class in any source file. The static constructor of MyPlugin class wil=
l create a static object, so you do not need to do this manually in a cpp f=
ile. The static constructor also calls Plugins::registerPlugin on the objec=
t, so it is also automatically registered. Just by a including header file.=
</div><div><br></div><div>After reading your comments I found that there is=
 actually no need for static destructor. As you can create a static object =
in static constructor, then regular destructor can perform a deregistration=
.. According to this, there is no longer need to consider the execution orde=
r.</div><div><br></div><div>Briefly, the linker should now operate this way=
:</div><div><ul><li>Call static constructors form all translation units and=
 libs<br></li><li>Call constructors for global variables (as usual)<br></li=
><li>Call main() function (as usual)<br></li><li>Call destructors for globa=
l variables (as usual)</li></ul><div><span style=3D"line-height: 17px;">Ple=
ase correct me if I am missing something here: If lib file have a static co=
nstructor providing plugin registration, it will be automatically executed =
and there is no longer need to provide a header file associated with the li=
b to use it in a project.</span></div></div></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dc2fc694-5dba-44c3-9451-5b0f98880878%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dc2fc694-5dba-44c3-9451-5b0f98880878=
%40isocpp.org</a>.<br />

------=_Part_660_186068126.1469207462446--

------=_Part_659_855157567.1469207462446--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 22 Jul 2016 10:43:38 -0700
Raw View
On sexta-feira, 22 de julho de 2016 10:11:02 PDT Mariusz Moczala wrote:
> Let=E2=80=99s consider the plug-in registration. Currently in C++ to exec=
ute class
> code, you need to at least create an object to execute default
> constructor=E2=80=99s code. You can also call a static function. However =
to
> register a new plug-in, programmer have to write some code.

Yes, it's an issue we have with plugin registration in Qt.

> With static constructors you can just add a cpp / obj / lib file into you=
r
> project.=20

That's not how the linkers work. If the plugin is in a static library (.a o=
r=20
..lib file), you have to somehow *use* the file before the linker will consi=
der=20
it. You need to call a function or use a variable defined in the specific .=
o or=20
..obj file that the contains the registration code.

The most obvious solution is to call the registration function.

But this highlights the other problem of your proposal: your static=20
constructors and destructors are run despite never being ODR-used. They sim=
ply=20
exist and therefore should be called, in an order that the compiler doesn't=
=20
know but should.

> Or just include a header file with above class in any source file.
> The static constructor of MyPlugin class will create a static object, so
> you do not need to do this manually in a cpp file. The static constructor
> also calls Plugins::registerPlugin on the object, so it is also
> automatically registered. Just by a including header file.

If you're going to include a header, then you could continue to use the=20
existing functionality. The only difference from what you're proposing to w=
hat=20
exists is that your header could be included from multiple translation unit=
s=20
without causing duplicate definitions.

> After reading your comments I found that there is actually no need for
> static destructor. As you can create a static object in static constructo=
r,
> then regular destructor can perform a deregistration. According to this,
> there is no longer need to consider the execution order.
>=20
> Briefly, the linker should now operate this way:
>=20
>    - Call static constructors form all translation units and libs

What order?

>    - Call constructors for global variables (as usual)
>    - Call main() function (as usual)
>    - Call destructors for global variables (as usual)
>=20
> Please correct me if I am missing something here: If lib file have a stat=
ic
> constructor providing plugin registration, it will be automatically
> executed and there is no longer need to provide a header file associated
> with the lib to use it in a project.

Except for the ODR-use.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/8768487.N6oa7PPqFV%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Jul 2016 10:45:29 -0700 (PDT)
Raw View
------=_Part_970_1893804595.1469209529406
Content-Type: multipart/alternative;
 boundary="----=_Part_971_1181160838.1469209529406"

------=_Part_971_1181160838.1469209529406
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Friday, July 22, 2016 at 1:11:02 PM UTC-4, Mariusz Moczala wrote:
>
> Thank you very much for all comments. Please have a look at the simplifie=
d=20
> code once again:
>
> class MyPlugin : public Plugin {
>   public:
>     static MyPlugin() {
>       static MyPlugin myPlugin;
>       Plugins::registerPlugin(myPlugin);
>     }
>     ~MyPlugin() {
>       Plugins::unregisterPlugin(*this);
>     }
> };
>
> This is a complete, executable code. Previously I have forgotten static=
=20
> keyword for getPluginInstance function. Thank you for pointing this out!
>
> Let=E2=80=99s consider the plug-in registration. Currently in C++ to exec=
ute class=20
> code, you need to at least create an object to execute default=20
> constructor=E2=80=99s code. You can also call a static function. However =
to=20
> register a new plug-in, programmer have to write some code.
>

So do you. You had to write the static constructor in question. Something=
=20
which could have been done like this:

class MyPlugin : public Plugin {
  public:
    ~MyPlugin() {
      Plugins::unregisterPlugin(*this);
    }

  private:
    struct Reg
    {
      Reg() {
        static MyPlugin myPlugin;
        Plugins::registerPlugin(myPlugin);
      }
    };

    static inline Reg register;
};

So why do we need a way to do something that we already know how to do?
=20

> With static constructors you can just add a cpp / obj / lib file into you=
r=20
> project. Or just include a header file with above class in any source fil=
e.
> =20
>
The static constructor of MyPlugin class will create a static object, so=20
> you do not need to do this manually in a cpp file. The static constructor=
=20
> also calls Plugins::registerPlugin on the object, so it is also=20
> automatically registered. Just by a including header file.
>
> After reading your comments I found that there is actually no need for=20
> static destructor. As you can create a static object in static constructo=
r,=20
> then regular destructor can perform a deregistration. According to this,=
=20
> there is no longer need to consider the execution order.
>
> Briefly, the linker should now operate this way:
>
>    - Call static constructors form all translation units and libs
>    - Call constructors for global variables (as usual)
>    - Call main() function (as usual)
>    - Call destructors for global variables (as usual)
>
> Please correct me if I am missing something here: If lib file have a=20
> static constructor providing plugin registration, it will be automaticall=
y=20
> executed and there is no longer need to provide a header file associated=
=20
> with the lib to use it in a project.
>

Allow me to restate what you just said:

Please correct me if I am missing something here: If lib file have a static=
=20
> *object* providing plugin registration, it will be automatically executed=
=20
> and there is no longer need to provide a header file associated with the=
=20
> lib to use it in a project.
>

So why do we need a static constructor if a static object will do the exact=
=20
same thing? You're not giving us something new; you're only creating a=20
*slightly* more convenient way to do it.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7834c343-e72b-4f34-a030-e244d7d38f94%40isocpp.or=
g.

------=_Part_971_1181160838.1469209529406
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, July 22, 2016 at 1:11:02 PM UTC-4, Mariusz Mocz=
ala wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v>Thank you very much for all comments. Please have a look at the simplifie=
d code once again:</div><div><br></div><font face=3D"courier new, monospace=
">class MyPlugin : public Plugin {<br>=C2=A0 public:<br>=C2=A0 =C2=A0 stati=
c MyPlugin() {<br></font><span style=3D"font-family:&quot;courier new&quot;=
,monospace">=C2=A0 =C2=A0 =C2=A0 static MyPlugin myPlugin;</span><br style=
=3D"font-family:&quot;courier new&quot;,monospace"><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 =C2=A0 Plugins::registerPlugin(</font><spa=
n style=3D"font-family:&quot;courier new&quot;,monospace">myPlug<wbr>in</sp=
an><font face=3D"courier new, monospace">);<br>=C2=A0 =C2=A0 }<br>=C2=A0 =
=C2=A0 ~MyPlugin() {<br>=C2=A0 =C2=A0 =C2=A0 Plugins::unregisterPlugin(*<wb=
r>this);<br>=C2=A0 =C2=A0 }<br>};</font><div><br></div><div>This is a compl=
ete, executable code. Previously I have forgotten static keyword for getPlu=
ginInstance function. Thank you for pointing this out!</div><div><br></div>=
<div>Let=E2=80=99s consider the plug-in registration. Currently in C++ to e=
xecute class code, you need to at least create an object to execute default=
 constructor=E2=80=99s code. You can also call a static function. However t=
o register a new plug-in, programmer have to write some code.</div></div></=
div></blockquote><div><br>So do you. You had to write the static constructo=
r in question. Something which could have been done like this:<br><br><div =
class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border=
-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">MyPlugin</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">public</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">Plugin</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">public</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">~</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">MyPlugin</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #606;"=
 class=3D"styled-by-prettify">Plugins</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">unregisterPlugin</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(*</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">this</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">private</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Reg</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Reg</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">MyPlugin</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> myPlugin</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #606;" class=3D"styled-by-prettify">Plugins</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">registerPlugin</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">myPlugin</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">static</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">inline</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Reg</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">register</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>};</span></div></code></div><br>So why do we need a way to do something th=
at we already know how to do?<br>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><div></div><div>With static constructo=
rs you can just add a cpp / obj / lib file into your project. Or just inclu=
de a header file with above class in any source file.<br>=C2=A0</div></div>=
</div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div><div>The static constructor of MyPlugin class will create a stat=
ic object, so you do not need to do this manually in a cpp file. The static=
 constructor also calls Plugins::registerPlugin on the object, so it is als=
o automatically registered. Just by a including header file.</div><div><br>=
</div><div>After reading your comments I found that there is actually no ne=
ed for static destructor. As you can create a static object in static const=
ructor, then regular destructor can perform a deregistration. According to =
this, there is no longer need to consider the execution order.</div><div><b=
r></div><div>Briefly, the linker should now operate this way:</div><div><ul=
><li>Call static constructors form all translation units and libs<br></li><=
li>Call constructors for global variables (as usual)<br></li><li>Call main(=
) function (as usual)<br></li><li>Call destructors for global variables (as=
 usual)</li></ul><div><span style=3D"line-height:17px">Please correct me if=
 I am missing something here: If lib file have a static constructor providi=
ng plugin registration, it will be automatically executed and there is no l=
onger need to provide a header file associated with the lib to use it in a =
project.</span></div></div></div></div></blockquote><div><br>Allow me to re=
state what you just said:<br><br><blockquote style=3D"margin: 0px 0px 0px 0=
..8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=
=3D"gmail_quote">Please correct me if I am missing something here: <span st=
yle=3D"line-height:17px">If lib file have a static <b>object</b>=20
providing plugin registration, it will be automatically executed and=20
there is no longer need to provide a header file associated with the lib
 to use it in a project.</span><br><span style=3D"line-height:17px"></span>=
</blockquote><span style=3D"line-height:17px"><br>So why do we need a stati=
c constructor if a static object will do the exact same thing? You&#39;re n=
ot giving us something new; you&#39;re only creating a <i>slightly</i> more=
 convenient way to do it.<br></span></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7834c343-e72b-4f34-a030-e244d7d38f94%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7834c343-e72b-4f34-a030-e244d7d38f94=
%40isocpp.org</a>.<br />

------=_Part_971_1181160838.1469209529406--

------=_Part_970_1893804595.1469209529406--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Fri, 22 Jul 2016 23:00:55 -0700 (PDT)
Raw View
------=_Part_1355_1908931512.1469253655878
Content-Type: multipart/alternative;
 boundary="----=_Part_1356_1008220106.1469253655878"

------=_Part_1356_1008220106.1469253655878
Content-Type: text/plain; charset=UTF-8


>
> So why do we need a static constructor if a static object will do the
> exact same thing? You're not giving us something new; you're only creating
> a *slightly* more convenient way to do it.
>

Static object with nontrivial constructor in a library you rae linking with:
 * might be some dead code you don't need (but might be needed by other
code base which uses this static object). In this case constructor call
might be freely elliminated by LTO
 * or can be a hack in order to have some code which do some lmportant
library initializations and must never be eliminated by LTO

Static class constructor is not "more convenient way to have class level or
library level initialization in C++". Is completely new feature which
provide you the only way to have such initialization. Current approach is
attempt to use some side-effect of another feature which is not reliable in
real world compilers without disabling important optimizations (there are
tricks like get address of a dummy static registrator variable from some
function which will be called. Necessity to have such strange code is the
best motivation example why static constructors is good feature to add to
C++).

This feature opens posibility to deprecate and remove in C++2023 or 2026
requirement on static object constructor invocation if this static object
is mever used or used from unreachable code only (I'm unsure if such term
like "reachable code" is defined in the standard so might be required to
define it). I do want to rely on dead static elliminaion in case of static
linkage. The company I'm working in now bought Qt license for 2 reasons: 1)
QML compiler 2) Static linking with Qt gives smaller APK on android. Binary
size reduce might be even more efficient with some help from the new
laguage standards.

Sergey Vidyuk

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0582c00e-b1dd-4502-a68b-b0967aaed0bc%40isocpp.org.

------=_Part_1356_1008220106.1469253655878
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><span style=3D"line-height:17px"></span><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><span style=3D"line-heigh=
t:17px">So why do we need a static constructor if a static object will do t=
he exact same thing? You&#39;re not giving us something new; you&#39;re onl=
y creating a <i>slightly</i> more convenient way to do it.<br></span></div>=
</div></blockquote><div><br>Static object with nontrivial constructor in a =
library you rae linking with:<br>=C2=A0* might be some dead code you don&#3=
9;t need (but might be needed by other code base which uses this static obj=
ect). In this case constructor call might be freely elliminated by LTO<br>=
=C2=A0* or can be a hack in order to have some code which do some lmportant=
 library initializations and must never be eliminated by LTO<br><br>Static =
class constructor is not &quot;more convenient way to have class level or l=
ibrary level initialization in C++&quot;. Is completely new feature which p=
rovide you the only way to have such initialization. Current approach is at=
tempt to use some side-effect of another feature which is not reliable in r=
eal world compilers without disabling important optimizations (there are tr=
icks like get address of a dummy static registrator variable from some func=
tion which will be called. Necessity to have such strange code is the best =
motivation example why static constructors is good feature to add to C++).<=
br><br>This feature opens posibility to deprecate and remove in C++2023 or =
2026 requirement on static object constructor invocation if this static obj=
ect is mever used or used from unreachable code only (I&#39;m unsure if suc=
h term like &quot;reachable code&quot; is defined in the standard so might =
be required to define it). I do want to rely on dead static elliminaion in =
case of static linkage. The company I&#39;m working in now bought Qt licens=
e for 2 reasons: 1) QML compiler 2) Static linking with Qt gives smaller AP=
K on android. Binary size reduce might be even more efficient with some hel=
p from the new laguage standards.<br><br>Sergey Vidyuk<br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0582c00e-b1dd-4502-a68b-b0967aaed0bc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0582c00e-b1dd-4502-a68b-b0967aaed0bc=
%40isocpp.org</a>.<br />

------=_Part_1356_1008220106.1469253655878--

------=_Part_1355_1908931512.1469253655878--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Sat, 23 Jul 2016 02:20:48 -0700 (PDT)
Raw View
------=_Part_1329_365572062.1469265648810
Content-Type: multipart/alternative;
 boundary="----=_Part_1330_1576367003.1469265648810"

------=_Part_1330_1576367003.1469265648810
Content-Type: text/plain; charset=UTF-8

Thank you very much for all constructive comments!



I would like to propose one extension to the static class constructor. It
should also allow to initialize static class variables through member
initializer list, similarly to non-static class constructor for non-static
members:

class MyPlugin
{
    public:

        static int abc;
        static MyPlugin() : abc(4) { }
};



So why do we need a static constructor if a static object will do the exact
> same thing? You're not giving us something new; you're only creating a
> slightly more convenient way to do it.

To have a static object you have to create it first, somewhere outside the
class. Static class constructor allows you to do this within a class body.
Please consider following example with a macro definition like this:

#define REGISTER_PLUGIN(Plugin) class __Init##Plugin##_t { public:
__Init##Plugin##_t() { static Plugin plugin;
Plugins::registerPlugin(plugin); } } __init##Plugin

The static class constructor allows you to avoid preprocessor usage and to
do this with "a slightly more convenient way". :)



Regarding ODR: I need to think it out carefully for different cases. I'll
come  with this later.



Thanks,
Mariusz

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335%40isocpp.org.

------=_Part_1330_1576367003.1469265648810
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thank you very much for all constructive comments!</d=
iv><div><br></div><div><br></div><div><br></div><div>I would like to propos=
e one extension to the static class constructor. It should also allow to in=
itialize static class variables through member initializer list, similarly =
to non-static class constructor for non-static members:</div><div><br></div=
><div><div>class MyPlugin</div><div>{</div><div>=C2=A0 =C2=A0 public:</div>=
<div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static int abc;</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 static MyPlugin() : abc(4) { }</div><div>};<br>=
</div></div><div><br></div><div><br></div><div><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px=
; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-=
left: 1ex;">So why do we need a static constructor if a static object will =
do the exact same thing? You&#39;re not giving us something new; you&#39;re=
 only creating a slightly more convenient way to do it.</blockquote><div>To=
 have a static object you have to create it first, somewhere outside the cl=
ass. Static class constructor allows you to do this within a class body. Pl=
ease consider following example with a macro definition like this:</div><di=
v><br></div><div>#define REGISTER_PLUGIN(Plugin) class __Init##Plugin##_t {=
 public: __Init##Plugin##_t() { static=C2=A0Plugin=C2=A0plugin; Plugins::re=
gisterPlugin(plugin); } } __init##Plugin</div><div><br></div><div>The stati=
c class constructor allows you to avoid preprocessor usage and to do this w=
ith &quot;a slightly more convenient way&quot;. :)</div><div><br></div><div=
><br></div><div><br></div><div>Regarding ODR: I need to think it out carefu=
lly for different cases. I&#39;ll come =C2=A0with this later.</div><div><br=
></div><div><br></div><div><br></div><div>Thanks,</div><div>Mariusz</div></=
div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335=
%40isocpp.org</a>.<br />

------=_Part_1330_1576367003.1469265648810--

------=_Part_1329_365572062.1469265648810--

.


Author: Robert Bielik <robert.bielik@gmail.com>
Date: Sat, 23 Jul 2016 12:09:50 +0200
Raw View
--001a1142d01c76df0c05384ac0ac
Content-Type: text/plain; charset=UTF-8

+1 for this as I've on many occasions missed the possibility to have
non-header exposed static initialization of polymorphic objects in
libraries.

Regards
/R

2016-07-23 11:20 GMT+02:00 Mariusz Moczala <mmoczala@gmail.com>:

> Thank you very much for all constructive comments!
>
>
>
> I would like to propose one extension to the static class constructor. It
> should also allow to initialize static class variables through member
> initializer list, similarly to non-static class constructor for non-static
> members:
>
> class MyPlugin
> {
>     public:
>
>         static int abc;
>         static MyPlugin() : abc(4) { }
> };
>
>
>
> So why do we need a static constructor if a static object will do the
>> exact same thing? You're not giving us something new; you're only creating
>> a slightly more convenient way to do it.
>
> To have a static object you have to create it first, somewhere outside the
> class. Static class constructor allows you to do this within a class body.
> Please consider following example with a macro definition like this:
>
> #define REGISTER_PLUGIN(Plugin) class __Init##Plugin##_t { public:
> __Init##Plugin##_t() { static Plugin plugin;
> Plugins::registerPlugin(plugin); } } __init##Plugin
>
> The static class constructor allows you to avoid preprocessor usage and to
> do this with "a slightly more convenient way". :)
>
>
>
> Regarding ODR: I need to think it out carefully for different cases. I'll
> come  with this later.
>
>
>
> Thanks,
> Mariusz
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHzA3cOEUSz8jKTrwxFdDK1BUNSkQspdqHfrRp0RbH0NPXWw%40mail.gmail.com.

--001a1142d01c76df0c05384ac0ac
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">+1 for this as I&#39;ve on many occasions missed the possi=
bility to have non-header exposed static initialization of polymorphic obje=
cts in libraries.<div><br></div><div>Regards</div><div>/R</div></div><div c=
lass=3D"gmail_extra"><br><div class=3D"gmail_quote">2016-07-23 11:20 GMT+02=
:00 Mariusz Moczala <span dir=3D"ltr">&lt;<a href=3D"mailto:mmoczala@gmail.=
com" target=3D"_blank">mmoczala@gmail.com</a>&gt;</span>:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>Thank you very much for all construc=
tive comments!</div><div><br></div><div><br></div><div><br></div><div>I wou=
ld like to propose one extension to the static class constructor. It should=
 also allow to initialize static class variables through member initializer=
 list, similarly to non-static class constructor for non-static members:</d=
iv><div><br></div><div><div>class MyPlugin</div><div>{</div><div>=C2=A0 =C2=
=A0 public:</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static int=
 abc;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static MyPlugin() : abc(4) { }<=
/div><div>};<br></div></div><span class=3D""><div><br></div><div><br></div>=
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb=
(204,204,204);padding-left:1ex">So why do we need a static constructor if a=
 static object will do the exact same thing? You&#39;re not giving us somet=
hing new; you&#39;re only creating a slightly more convenient way to do it.=
</blockquote></span><div>To have a static object you have to create it firs=
t, somewhere outside the class. Static class constructor allows you to do t=
his within a class body. Please consider following example with a macro def=
inition like this:</div><div><br></div><div>#define REGISTER_PLUGIN(Plugin)=
 class __Init##Plugin##_t { public: __Init##Plugin##_t() { static=C2=A0Plug=
in=C2=A0plugin; Plugins::registerPlugin(plugin); } } __init##Plugin</div><d=
iv><br></div><div>The static class constructor allows you to avoid preproce=
ssor usage and to do this with &quot;a slightly more convenient way&quot;. =
:)</div><div><br></div><div><br></div><div><br></div><div>Regarding ODR: I =
need to think it out carefully for different cases. I&#39;ll come =C2=A0wit=
h this later.</div><div><br></div><div><br></div><div><br></div><div>Thanks=
,</div><div>Mariusz</div></div><span class=3D"">

<p></p>

-- <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+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-428d-a87d-f6d7732db335%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a027b6eb-30ba-=
428d-a87d-f6d7732db335%40isocpp.org</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAEvHzA3cOEUSz8jKTrwxFdDK1BUNSkQspdqH=
frRp0RbH0NPXWw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHzA3cOEUSz8jK=
TrwxFdDK1BUNSkQspdqHfrRp0RbH0NPXWw%40mail.gmail.com</a>.<br />

--001a1142d01c76df0c05384ac0ac--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 Jul 2016 08:39:37 -0700 (PDT)
Raw View
------=_Part_55_1175584278.1469288377976
Content-Type: multipart/alternative;
 boundary="----=_Part_56_1254306418.1469288377976"

------=_Part_56_1254306418.1469288377976
Content-Type: text/plain; charset=UTF-8

On Saturday, July 23, 2016 at 2:00:56 AM UTC-4, Sergey Vidyuk wrote:
>
> So why do we need a static constructor if a static object will do the
>> exact same thing? You're not giving us something new; you're only creating
>> a *slightly* more convenient way to do it.
>>
>
> Static object with nontrivial constructor in a library you rae linking
> with:
>  * might be some dead code you don't need (but might be needed by other
> code base which uses this static object). In this case constructor call
> might be freely elliminated by LTO
>
 * or can be a hack in order to have some code which do some lmportant
> library initializations and must never be eliminated by LTO
>

Inline variables
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf>seem to
solve this problem. From the PDF, I gather that the intent is that the
constructor/destructor for inline variables are always called, whether they
are ODR used or not. And therefore, you can rely on their side-effects.

Static class constructor is not "more convenient way to have class level or
> library level initialization in C++". Is completely new feature which
> provide you the only way to have such initialization. Current approach is
> attempt to use some side-effect of another feature which is not reliable in
> real world compilers without disabling important optimizations (there are
> tricks like get address of a dummy static registrator variable from some
> function which will be called. Necessity to have such strange code is the
> best motivation example why static constructors is good feature to add to
> C++).
>

If the standard says that the constructors of static objects must be
called, then they must be called. And "real world compilers" that stop
doing that are *broken*.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f08d35e6-cf19-4029-a729-7550d144dc10%40isocpp.org.

------=_Part_56_1254306418.1469288377976
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, July 23, 2016 at 2:00:56 AM UTC-4, Sergey Vid=
yuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><sp=
an style=3D"line-height:17px"></span><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div><span style=3D"line-height:17px">So why do we need =
a static constructor if a static object will do the exact same thing? You&#=
39;re not giving us something new; you&#39;re only creating a <i>slightly</=
i> more convenient way to do it.<br></span></div></div></blockquote><div><b=
r>Static object with nontrivial constructor in a library you rae linking wi=
th:<br>=C2=A0* might be some dead code you don&#39;t need (but might be nee=
ded by other code base which uses this static object). In this case constru=
ctor call might be freely elliminated by LTO=C2=A0</div></div></blockquote>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0* =
or can be a hack in order to have some code which do some lmportant library=
 initializations and must never be eliminated by LTO<br></div></div></block=
quote><div><br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/paper=
s/2015/n4424.pdf">Inline variables </a>seem to solve this problem. From the=
 PDF, I gather that the intent is that the constructor/destructor for inlin=
e variables are always called, whether they are ODR used or not. And theref=
ore, you can rely on their side-effects.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div>Static class constructor is n=
ot &quot;more convenient way to have class level or library level initializ=
ation in C++&quot;. Is completely new feature which provide you the only wa=
y to have such initialization. Current approach is attempt to use some side=
-effect of another feature which is not reliable in real world compilers wi=
thout disabling important optimizations (there are tricks like get address =
of a dummy static registrator variable from some function which will be cal=
led. Necessity to have such strange code is the best motivation example why=
 static constructors is good feature to add to C++).<br></div></div></block=
quote><div><br>If the standard says that the constructors of static objects=
 must be called, then they must be called. And &quot;real world compilers&q=
uot; that stop doing that are <i>broken</i>.</div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f08d35e6-cf19-4029-a729-7550d144dc10%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f08d35e6-cf19-4029-a729-7550d144dc10=
%40isocpp.org</a>.<br />

------=_Part_56_1254306418.1469288377976--

------=_Part_55_1175584278.1469288377976--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 Jul 2016 08:41:57 -0700 (PDT)
Raw View
------=_Part_1160_1994761292.1469288517169
Content-Type: multipart/alternative;
 boundary="----=_Part_1161_495232907.1469288517169"

------=_Part_1161_495232907.1469288517169
Content-Type: text/plain; charset=UTF-8

On Saturday, July 23, 2016 at 5:20:49 AM UTC-4, Mariusz Moczala wrote:

> So why do we need a static constructor if a static object will do the
>> exact same thing? You're not giving us something new; you're only creating
>> a slightly more convenient way to do it.
>
> To have a static object you have to create it first, somewhere outside the
> class.
>

Inline variables
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf>are a
thing now. Or will be in C++17. So no, you don't; you can put that in a
header just fine.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ea005a8a-2fcf-4960-835c-272cbf00e11d%40isocpp.org.

------=_Part_1161_495232907.1469288517169
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, July 23, 2016 at 5:20:49 AM UTC-4, Mariusz Mo=
czala wrote:<div></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><div><div></div></div><div></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style=
:solid;border-left-color:rgb(204,204,204);padding-left:1ex">So why do we ne=
ed a static constructor if a static object will do the exact same thing? Yo=
u&#39;re not giving us something new; you&#39;re only creating a slightly m=
ore convenient way to do it.</blockquote><div>To have a static object you h=
ave to create it first, somewhere outside the class.</div></div></blockquot=
e><div><br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/20=
15/n4424.pdf">Inline variables </a>are a thing now. Or will be in C++17. So=
 no, you don&#39;t; you can put that in a header just fine.<br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ea005a8a-2fcf-4960-835c-272cbf00e11d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ea005a8a-2fcf-4960-835c-272cbf00e11d=
%40isocpp.org</a>.<br />

------=_Part_1161_495232907.1469288517169--

------=_Part_1160_1994761292.1469288517169--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Sat, 23 Jul 2016 09:54:14 -0700
Raw View
On s=C3=A1bado, 23 de julho de 2016 08:39:37 PDT Nicol Bolas wrote:
> Inline variables=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf>seem t=
o=20
> solve this problem. From the PDF, I gather that the intent is that the=20
> constructor/destructor for inline variables are always called, whether th=
ey=20
> are ODR used or not. And therefore, you can rely on their side-effects.

Has this been implemented as a proof of concept in any compler?

I don't remember this as a consequence of inline variables when we were=20
discussing them. They were either constexpr or evaluated on use, as opposed=
 to=20
intialised some time in the past.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/2922407.ZpVaH0O7Ye%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 Jul 2016 14:07:25 -0700 (PDT)
Raw View
------=_Part_1797_191538098.1469308045687
Content-Type: multipart/alternative;
 boundary="----=_Part_1798_164564079.1469308045687"

------=_Part_1798_164564079.1469308045687
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Saturday, July 23, 2016 at 12:54:20 PM UTC-4, Thiago Macieira wrote:
>
> On s=C3=A1bado, 23 de julho de 2016 08:39:37 PDT Nicol Bolas wrote:=20
> > Inline variables=20
> > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf>seem=
=20
> to=20
> > solve this problem. From the PDF, I gather that the intent is that the=
=20
> > constructor/destructor for inline variables are always called, whether=
=20
> they=20
> > are ODR used or not. And therefore, you can rely on their side-effects.=
=20
>
> Has this been implemented as a proof of concept in any compler?=20
>
> I don't remember this as a consequence of inline variables when we were=
=20
> discussing them. They were either constexpr or evaluated on use, as=20
> opposed to=20
> intialised some time in the past.
>

I don't know enough about that part of the standard to interpret what the=
=20
wording means in this regard. But the motivation section seems like it's=20
calling out the need to ODR-use such variables in order to be able to rely=
=20
on their constructor side-effects as one of the reasons for the feature. So=
=20
I assume that the wording introduces that ability.

But I could be wrong.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/22455f1d-3b8a-4559-9dce-51741c149397%40isocpp.or=
g.

------=_Part_1798_164564079.1469308045687
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, July 23, 2016 at 12:54:20 PM UTC-4, T=
hiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On s=C3=
=A1bado, 23 de julho de 2016 08:39:37 PDT Nicol Bolas wrote:
<br>&gt; Inline variables=20
<br>&gt; &lt;<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/=
2015/n4424.pdf" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4424.pdf\x26sa\x3dD\x26sntz\x3d1\x=
26usg\x3dAFQjCNHXcAOIgB0nUgU2zIgpR1dnRVAUYQ&#39;;return true;" onclick=3D"t=
his.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.or=
g%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4424.pdf\x26sa\x3dD\x26snt=
z\x3d1\x26usg\x3dAFQjCNHXcAOIgB0nUgU2zIgpR1dnRVAUYQ&#39;;return true;">http=
://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>n4424.pdf</a>=
&gt;seem to=20
<br>&gt; solve this problem. From the PDF, I gather that the intent is that=
 the=20
<br>&gt; constructor/destructor for inline variables are always called, whe=
ther they=20
<br>&gt; are ODR used or not. And therefore, you can rely on their side-eff=
ects.
<br>
<br>Has this been implemented as a proof of concept in any compler?
<br>
<br>I don&#39;t remember this as a consequence of inline variables when we =
were=20
<br>discussing them. They were either constexpr or evaluated on use, as opp=
osed to=20
<br>intialised some time in the past.<br></blockquote><div><br>I don&#39;t =
know enough about that part of the standard to interpret what the wording m=
eans in this regard. But the motivation section seems like it&#39;s calling=
 out the need to ODR-use such variables in order to be able to rely on thei=
r constructor side-effects as one of the reasons for the feature. So I assu=
me that the wording introduces that ability.<br><br>But I could be wrong.<b=
r></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/22455f1d-3b8a-4559-9dce-51741c149397%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/22455f1d-3b8a-4559-9dce-51741c149397=
%40isocpp.org</a>.<br />

------=_Part_1798_164564079.1469308045687--

------=_Part_1797_191538098.1469308045687--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Tue, 26 Jul 2016 07:49:19 -0700 (PDT)
Raw View
------=_Part_511_1674846357.1469544559222
Content-Type: multipart/alternative;
 boundary="----=_Part_512_1977594832.1469544559223"

------=_Part_512_1977594832.1469544559223
Content-Type: text/plain; charset=UTF-8



Hello once again,



Please tell me what do you think about the following example:



#include <cstdio>

#include <string>



class LogFile

{

    private:



        FILE *file;





    public:



        LogFile() :

            file(NULL)

        {

        }



        ~LogFile()

        {

            close();

        }



        void append(const char *fileName)

        {

            close();

            file = fopen(fileName, "a+t");

        }



        void close()

        {

            if(file) {

                fclose(file);

                file = NULL;

            }

        }



        bool isOpened() const

        {

            return file != NULL;

        }



        void write(const char *message)

        {

            fprintf(file, "%s\n", message);

        }

};



class Log

{

    private:



        static LogFile logFile;





    public:



        static Log()

        {

            logFile.append("log.txt");

            if(!logFile.isOpened())

                fprintf(stderr, "ERROR: Failed to create 'log.txt'
file.\n");

        }





    private:



        std::string str;





    public:



        ~Log()

        {

            logFile.write(str.c_str());

        }



        void write(const char *text)

        {

            if(str.length())

                str += "    ";

            str += text;

            str += '\n';

        }

};



int main()

{

    Log logAlpha, logNum;

    logAlpha.write("A message");

    logNum.write("1 message");

    logAlpha.write("B message");

    logNum.write("2 message");

    logAlpha.write("C message");

    logNum.write("3 message");



    return 0;

}



OUTPUT:



1 message

    2 message

    3 message



A message

    B message

    C message



Regarding the code marked in blue:

   - The static *logFile* variable is defined because a static class
   constructor is defined. The static variable can be also initialized
   through initializer list
   - The static class constructor is executed once, so you can
   perform actions like filie open
   - The static *logFile* variable will be destroyed on application
   termination as usual static variable
   - Is this a kind of a singleton or not?


Many thanks,

Mariusz



--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/92242832-a225-443f-9409-0703402a4f64%40isocpp.org.

------=_Part_512_1977594832.1469544559223
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><p class=3D"MsoNormal" style=3D"background-image: initial;=
 background-attachment: initial; background-size: initial; background-origi=
n: initial; background-clip: initial; background-position: initial; backgro=
und-repeat: initial;"><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><font size=3D"2">Hello once again,<o:p></o:p></font></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><font s=
ize=3D"2">Please tell me what do you think about the following example:<o:p=
></o:p></font></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">#include &lt;cst=
dio&gt;</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">#include &lt;str=
ing&gt;</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">class LogFile</s=
pan><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o=
:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">{</span><span la=
ng=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></=
font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 pr=
ivate:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"=
><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 FILE *file;</span><span lang=3D"EN-US" style=3D"font-family: =
Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 pu=
blic:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;">=
<o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 LogFile() :</span><span lang=3D"EN-US" style=3D"font-family: =
Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 file(NULL)</span><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 ~LogFile()</span><span lang=3D"EN-US" style=3D"font-family: A=
rial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</span><span lang=3D"EN-US" style=3D"fo=
nt-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 void append(const char *fileName)</span><span lang=3D"EN-US" =
style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</span><span lang=3D"EN-US" style=3D"fo=
nt-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D fopen(fileName,
&quot;a+t&quot;);</span><span lang=3D"EN-US" style=3D"font-family: Arial, s=
ans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 void close()</span><span lang=3D"EN-US" style=3D"font-family:=
 Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(file) {</span><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(file);</span><span lang=3D=
"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font>=
</p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D NULL;</span><span lang=
=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></fo=
nt></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-fami=
ly: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 bool isOpened() const</span><span lang=3D"EN-US" style=3D"fon=
t-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return file !=3D NULL;</span><span lang=3D"EN-U=
S" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 void write(const char *message)</span><span lang=3D"EN-US" st=
yle=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(file, &quot;%s\n&quot;,
message);</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-seri=
f;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">};</span><span l=
ang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span><=
/font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">class Log</span>=
<span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p><=
/span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">{</span><span la=
ng=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></=
font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
private:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif=
;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 static LogFile logFile;</span><span lang=3D"EN-US" style=3D"f=
ont-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
public:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 static Log()</span><span lang=3D"EN-US" style=3D"font-family:=
 Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.append(&quot;log.txt&quot;);</span><spa=
n lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></spa=
n></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(!logFile.isOpened())</span><span lang=3D"EN-=
US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &quot;ERROR: Fail=
ed
to create &#39;log.txt&#39; file.\n&quot;);</span><span lang=3D"EN-US" styl=
e=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; color: blue; border: 1pt none windowtext; padding: 0cm;">=C2=
=A0 =C2=A0
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 pr=
ivate:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"=
><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 std::string str;</span><span lang=3D"EN-US" style=3D"font-fam=
ily: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 pu=
blic:</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;">=
<o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 ~Log()</span><span lang=3D"EN-US" style=3D"font-family: Arial=
, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.write(str.c_str());</span><span lang=3D=
"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font>=
</p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 void write(const char *text)</span><span lang=3D"EN-US" style=
=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</span><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if(str.length())</span><span lang=3D"EN-US" sty=
le=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D &quot;
=C2=A0 =C2=A0&quot;;</span><span lang=3D"EN-US" style=3D"font-family: Arial=
, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D text;</span><span lang=3D"EN-US" style=
=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"font-family: &quot;Courie=
r New&quot;; border: 1pt none windowtext; padding: 0cm;">str +=3D &#39;\n&#=
39;;</span><span style=3D"font-family: Arial, sans-serif;"><o:p></o:p></spa=
n></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span style=3D"font-family: &quot;Courier New&quot;; =
border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</=
span><span style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></fo=
nt></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">};</span><span l=
ang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span><=
/font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">int main()</span=
><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p>=
</span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">{</span><span la=
ng=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></=
font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 Lo=
g logAlpha, logNum;</span><span lang=3D"EN-US" style=3D"font-family: Arial,=
 sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gAlpha.write(&quot;A message&quot;);</span><span lang=3D"EN-US" style=3D"fo=
nt-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gNum.write(&quot;1 message&quot;);</span><span lang=3D"EN-US" style=3D"font=
-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gAlpha.write(&quot;B message&quot;);</span><span lang=3D"EN-US" style=3D"fo=
nt-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gNum.write(&quot;2 message&quot;);</span><span lang=3D"EN-US" style=3D"font=
-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gAlpha.write(&quot;C message&quot;);</span><span lang=3D"EN-US" style=3D"fo=
nt-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 lo=
gNum.write(&quot;3 message&quot;);</span><span lang=3D"EN-US" style=3D"font=
-family: Arial, sans-serif;"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 re=
turn 0;</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">}</span><span la=
ng=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p></span></=
font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><font s=
ize=3D"2">OUTPUT:<o:p></o:p></font></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">1 message</span>=
<span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p><=
/span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 2 =
message</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 3 =
message</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">A message</span>=
<span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p></o:p><=
/span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 B =
message</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: &quot;Cour=
ier New&quot;; border: 1pt none windowtext; padding: 0cm;">=C2=A0 =C2=A0 C =
message</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;=
"><o:p></o:p></span></font></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><f=
ont size=3D"2">=C2=A0</font></o:p></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><font size=3D"2"><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif;">Regarding the code marked in</span><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif;">=C2=A0</span><span lang=3D"EN-US" style=3D=
"font-family: Arial, sans-serif; color: blue; border: 1pt none windowtext; =
padding: 0cm;">blue</span><span lang=3D"EN-US" style=3D"font-family: Arial,=
 sans-serif;">:<o:p></o:p></span></font></p>

<ul type=3D"disc">
 <li class=3D"MsoNormal" style=3D"line-height: 9.15pt; background-image: in=
itial; background-attachment: initial; background-size: initial; background=
-origin: initial; background-clip: initial; background-position: initial; b=
ackground-repeat: initial;"><font size=3D"2"><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif; border: 1pt none windowtext; padding: 0cm;"=
>The static</span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-se=
rif;">=C2=A0</span><i><span lang=3D"EN-US" style=3D"font-family: Arial, san=
s-serif; border: 1pt none windowtext; padding: 0cm;">logFile</span></i><spa=
n lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;">=C2=A0</span><sp=
an lang=3D"EN-US" style=3D"font-family: Arial, sans-serif; border: 1pt none=
 windowtext; padding: 0cm;">variable is
     defined because a static class constructor is defined. </span><span st=
yle=3D"font-family: Arial, sans-serif; border: 1pt none windowtext; padding=
: 0cm;">The static variable can be also
     initialized through initializer list</span><span style=3D"font-family:=
 Arial, sans-serif;"><o:p></o:p></span></font></li>
 <li class=3D"MsoNormal" style=3D"line-height: 9.15pt; background-image: in=
itial; background-attachment: initial; background-size: initial; background=
-origin: initial; background-clip: initial; background-position: initial; b=
ackground-repeat: initial;"><font size=3D"2"><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif; border: 1pt none windowtext; padding: 0cm;"=
>The static class
     constructor is executed once, so you can perform=C2=A0actions
     like=C2=A0filie open</span><span lang=3D"EN-US" style=3D"font-family: =
Arial, sans-serif;"><o:p></o:p></span></font></li>
 <li class=3D"MsoNormal" style=3D"line-height: 9.15pt; background-image: in=
itial; background-attachment: initial; background-size: initial; background=
-origin: initial; background-clip: initial; background-position: initial; b=
ackground-repeat: initial;"><font size=3D"2"><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif; border: 1pt none windowtext; padding: 0cm;"=
>The=C2=A0static=C2=A0</span><i><span lang=3D"EN-US" style=3D"font-family: =
Arial, sans-serif;">logFile</span></i><span lang=3D"EN-US" style=3D"font-fa=
mily: Arial, sans-serif; border: 1pt none windowtext; padding: 0cm;">=C2=A0=
variable
     will be destroyed on application termination as usual static variable<=
/span><span lang=3D"EN-US" style=3D"font-family: Arial, sans-serif;"><o:p><=
/o:p></span></font></li>
 <li class=3D"MsoNormal" style=3D"line-height: 9.15pt; background-image: in=
itial; background-attachment: initial; background-size: initial; background=
-origin: initial; background-clip: initial; background-position: initial; b=
ackground-repeat: initial;"><font size=3D"2"><span lang=3D"EN-US" style=3D"=
font-family: Arial, sans-serif; border: 1pt none windowtext; padding: 0cm;"=
>Is this a kind of a
     singleton or not?</span></font></li></ul>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span style=3D"font-family: Arial, sans-serif;"><font size=3D"2"><br><=
/font></span></p><p class=3D"MsoNormal" style=3D"background-image: initial;=
 background-attachment: initial; background-size: initial; background-origi=
n: initial; background-clip: initial; background-position: initial; backgro=
und-repeat: initial;"><span style=3D"font-family: Arial, sans-serif;"><font=
 size=3D"2">Many thanks,<o:p></o:p></font></span></p>

<p class=3D"MsoNormal" style=3D"background-image: initial; background-attac=
hment: initial; background-size: initial; background-origin: initial; backg=
round-clip: initial; background-position: initial; background-repeat: initi=
al;"><span style=3D"font-family: Arial, sans-serif;"><font size=3D"2">Mariu=
sz<o:p></o:p></font></span></p>

<p class=3D"MsoNormal"><o:p><font size=3D"2">=C2=A0</font></o:p></p></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/92242832-a225-443f-9409-0703402a4f64%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/92242832-a225-443f-9409-0703402a4f64=
%40isocpp.org</a>.<br />

------=_Part_512_1977594832.1469544559223--

------=_Part_511_1674846357.1469544559222--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Tue, 26 Jul 2016 07:50:34 -0700 (PDT)
Raw View
------=_Part_205_300685825.1469544634131
Content-Type: multipart/alternative;
 boundary="----=_Part_206_1014511254.1469544634132"

------=_Part_206_1014511254.1469544634132
Content-Type: text/plain; charset=UTF-8

Hello once again,

Please tell me what do you think about the following example:

#include <cstdio>
#include <string>

class LogFile
{
    private:

        FILE *file;


    public:

        LogFile() :
            file(NULL)
        {
        }

        ~LogFile()
        {
            close();
        }

        void append(const char *fileName)
        {
            close();
            file = fopen(fileName, "a+t");
        }

        void close()
        {
            if(file) {
                fclose(file);
                file = NULL;
            }
        }

        bool isOpened() const
        {
            return file != NULL;
        }

        void write(const char *message)
        {
            fprintf(file, "%s\n", message);
        }
};

class Log
{
    private:

        static LogFile logFile;


    public:

        static Log()
        {
            logFile.append("log.txt");
            if(!logFile.isOpened())
                fprintf(stderr, "ERROR: Failed to create 'log.txt'
file.\n");
        }


    private:

        std::string str;


    public:

        ~Log()
        {
            logFile.write(str.c_str());
        }

        void write(const char *text)
        {
            if(str.length())
                str += "    ";
            str += text;
            str += '\n';
        }
};

int main()
{
    Log logAlpha, logNum;
    logAlpha.write("A message");
    logNum.write("1 message");
    logAlpha.write("B message");
    logNum.write("2 message");
    logAlpha.write("C message");
    logNum.write("3 message");

    return 0;
}

OUTPUT:

1 message
    2 message
    3 message

A message
    B message
    C message

Regarding the code marked in blue:

   - The static logFile variable is defined because a static class
   constructor is defined. The static variable can be also initialized through
   initializer list
   - The static class constructor is executed once, so you can perform
   actions like filie open
   - The static logFile variable will be destroyed on application
   termination as usual static variable
   - Is this a kind of a singleton or not?


Many thanks,
Mariusz

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203%40isocpp.org.

------=_Part_206_1014511254.1469544634132
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello once again,</div><div><br></div><div>Please tel=
l me what do you think about the following example:</div><div><br></div><di=
v><font face=3D"courier new, monospace">#include &lt;cstdio&gt;</font></div=
><div><font face=3D"courier new, monospace">#include &lt;string&gt;</font><=
/div><div><font face=3D"courier new, monospace"><br></font></div><div><font=
 face=3D"courier new, monospace">class LogFile</font></div><div><font face=
=3D"courier new, monospace">{</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 private:</font></div><div><font face=3D"courier new=
, monospace"><br></font></div><div><font face=3D"courier new, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 FILE *file;</font></div><div><font face=3D"cour=
ier new, monospace"><br></font></div><div><font face=3D"courier new, monosp=
ace"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 public:</font></div><div><font face=3D"courier new, monospace"><br></fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 LogFile() :</font></div><div><font face=3D"courier new, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file(NULL)</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div>=
<div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</f=
ont></div><div><font face=3D"courier new, monospace"><br></font></div><div>=
<font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~LogFile(=
)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><fon=
t face=3D"courier new, monospace"><br></font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void append(const char *file=
Name)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =
=3D fopen(fileName, &quot;a+t&quot;);</font></div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=
=3D"courier new, monospace"><br></font></div><div><font face=3D"courier new=
, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void close()</font></div><div><fon=
t face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div=
><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 if(file) {</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(file);</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D NULL;</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br></font>=
</div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 bool isOpened() const</font></div><div><font face=3D"courier new, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courier =
new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return file !=3D =
NULL;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br>=
</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 void write(const char *message)</font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
fprintf(file, &quot;%s\n&quot;, message);</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font =
face=3D"courier new, monospace">};</font></div><div><font face=3D"courier n=
ew, monospace"><br></font></div><div><font face=3D"courier new, monospace">=
class Log</font></div><div><font face=3D"courier new, monospace">{</font></=
div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 private:</font></div><div><font face=3D"courier new, monospace" color=
=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static LogFile logFile;</font><=
/div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></fon=
t></div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></=
font></div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=
=A0 =C2=A0 public:</font></div><div><font face=3D"courier new, monospace" c=
olor=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace=
" color=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static Log()</font></div><d=
iv><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace" colo=
r=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.append(&quo=
t;log.txt&quot;);</font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(!logFile.isOpe=
ned())</font></div><div><font face=3D"courier new, monospace" color=3D"#000=
0ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr=
, &quot;ERROR: Failed to create &#39;log.txt&#39; file.\n&quot;);</font></d=
iv><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace">=
<br></font></div><div><font face=3D"courier new, monospace"><br></font></di=
v><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 private:</font><=
/div><div><font face=3D"courier new, monospace"><br></font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::string st=
r;</font></div><div><font face=3D"courier new, monospace"><br></font></div>=
<div><font face=3D"courier new, monospace"><br></font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 public:</font></div><div><font fa=
ce=3D"courier new, monospace"><br></font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~Log()</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><di=
v><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 logFile.write(str.c_str());</font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void write(const char *text)</font></=
div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
{</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 if(str.length())</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 str +=3D &quot; =C2=A0 =C2=A0&quot;;</font></div><div><font face=3D"cou=
rier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D tex=
t;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D &#39;\n&#39;;</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div>=
<font face=3D"courier new, monospace">};</font></div><div><font face=3D"cou=
rier new, monospace"><br></font></div><div><font face=3D"courier new, monos=
pace">int main()</font></div><div><font face=3D"courier new, monospace">{</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 Log log=
Alpha, logNum;</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 logAlpha.write(&quot;A message&quot;);</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;1 message&qu=
ot;);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
logAlpha.write(&quot;B message&quot;);</font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;2 message&quot;);</font=
></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.wr=
ite(&quot;C message&quot;);</font></div><div><font face=3D"courier new, mon=
ospace">=C2=A0 =C2=A0 logNum.write(&quot;3 message&quot;);</font></div><div=
><font face=3D"courier new, monospace"><br></font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 return 0;</font></div><div><font face=
=3D"courier new, monospace">}</font></div><div><br></div><div>OUTPUT:</div>=
<div><br></div><div><font face=3D"courier new, monospace">1 message</font><=
/div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 2 message</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 3 message=
</font></div><div><font face=3D"courier new, monospace"><br></font></div><d=
iv><font face=3D"courier new, monospace">A message</font></div><div><font f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0 B message</font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 C message</font></div><div=
><br></div><div>Regarding the code marked in <font color=3D"#0000ff">blue</=
font>:</div><div><ul><li>The static logFile variable is defined because a s=
tatic class constructor is defined. The static variable can be also initial=
ized through initializer list<br></li><li>The static class constructor is e=
xecuted once, so you can perform actions like filie open<br></li><li>The st=
atic logFile variable will be destroyed on application termination as usual=
 static variable<br></li><li>Is this a kind of a singleton or not?<br></li>=
</ul></div><div><br></div><div>Many thanks,</div><div>Mariusz</div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203=
%40isocpp.org</a>.<br />

------=_Part_206_1014511254.1469544634132--

------=_Part_205_300685825.1469544634131--

.


Author: Patrice Roy <patricer@gmail.com>
Date: Tue, 26 Jul 2016 11:07:42 -0400
Raw View
--001a114e30dc3fb82505388b4302
Content-Type: text/plain; charset=UTF-8

Given that we can get the same effect with existing language features such
as :

class Log {
   struct LogFileHandler {
      LogFile file;
      LogFileHandler() {
         file.append("log.txt");
         if (!file.is_open())
            fprintf(stderr, "ERROR: Failed to create 'log.txt' file.\n");
      }
   };
   static LogFileHandler handler;
   std::string str;
public:
   ~Log() {
      handler.file.write(str.c_str());
   }
   void write(const char *text) {
      if (!str.empty())
         str += "    ";
      str += text;
      str += '\n';
   }
};

// ...
Log::LogFileHandler Log::handler;

.... I fail to see the gains from the additional syntax, at least in C++
(other languages like C# or Java gain from this, but they instantiate
objects quite differently). What does it bring that we cannot already do
with minimal effort?


2016-07-26 10:50 GMT-04:00 Mariusz Moczala <mmoczala@gmail.com>:

> Hello once again,
>
> Please tell me what do you think about the following example:
>
> #include <cstdio>
> #include <string>
>
> class LogFile
> {
>     private:
>
>         FILE *file;
>
>
>     public:
>
>         LogFile() :
>             file(NULL)
>         {
>         }
>
>         ~LogFile()
>         {
>             close();
>         }
>
>         void append(const char *fileName)
>         {
>             close();
>             file = fopen(fileName, "a+t");
>         }
>
>         void close()
>         {
>             if(file) {
>                 fclose(file);
>                 file = NULL;
>             }
>         }
>
>         bool isOpened() const
>         {
>             return file != NULL;
>         }
>
>         void write(const char *message)
>         {
>             fprintf(file, "%s\n", message);
>         }
> };
>
> class Log
> {
>     private:
>
>         static LogFile logFile;
>
>
>     public:
>
>         static Log()
>         {
>             logFile.append("log.txt");
>             if(!logFile.isOpened())
>                 fprintf(stderr, "ERROR: Failed to create 'log.txt'
> file.\n");
>         }
>
>
>     private:
>
>         std::string str;
>
>
>     public:
>
>         ~Log()
>         {
>             logFile.write(str.c_str());
>         }
>
>         void write(const char *text)
>         {
>             if(str.length())
>                 str += "    ";
>             str += text;
>             str += '\n';
>         }
> };
>
> int main()
> {
>     Log logAlpha, logNum;
>     logAlpha.write("A message");
>     logNum.write("1 message");
>     logAlpha.write("B message");
>     logNum.write("2 message");
>     logAlpha.write("C message");
>     logNum.write("3 message");
>
>     return 0;
> }
>
> OUTPUT:
>
> 1 message
>     2 message
>     3 message
>
> A message
>     B message
>     C message
>
> Regarding the code marked in blue:
>
>    - The static logFile variable is defined because a static class
>    constructor is defined. The static variable can be also initialized through
>    initializer list
>    - The static class constructor is executed once, so you can perform
>    actions like filie open
>    - The static logFile variable will be destroyed on application
>    termination as usual static variable
>    - Is this a kind of a singleton or not?
>
>
> Many thanks,
> Mariusz
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKiZDp2%3DanO%2B7tasGDbOpLB-5_zGJotZ%3DNOnthxh-%3Dm3EUVYmQ%40mail.gmail.com.

--001a114e30dc3fb82505388b4302
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Given that we can get the same effect with existing l=
anguage features such as :<br><br>class Log {<br>=C2=A0=C2=A0 struct LogFil=
eHandler {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 LogFile file;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 LogFileHandler() {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 file.append(&quot;log.txt&quot;);<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!file.is_open())<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fprintf(stderr, &quot;ERROR: =
Failed to create &#39;log.txt&#39; file.\n&quot;);<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0 };<br>=C2=A0=C2=A0 static LogFileHandler handle=
r;<br>=C2=A0=C2=A0 std::string str;<br>public:<br>=C2=A0=C2=A0 ~Log() {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 handler.file.write(str.c_str());<br>=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0 void write(const char *text) {<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 if (!str.empty())<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 str +=3D &quot;=C2=A0=C2=A0=C2=A0 &quot;;<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 str +=3D text;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 str +=3D &=
#39;\n&#39;;<br>=C2=A0=C2=A0 }<br>};<br><br>// ...<br>Log::LogFileHandler L=
og::handler;<br><br></div>... I fail to see the gains from the additional s=
yntax, at least in C++ (other languages like C# or Java gain from this, but=
 they instantiate objects quite differently). What does it bring that we ca=
nnot already do with minimal effort?<br><div><br></div></div><div class=3D"=
gmail_extra"><br><div class=3D"gmail_quote">2016-07-26 10:50 GMT-04:00 Mari=
usz Moczala <span dir=3D"ltr">&lt;<a href=3D"mailto:mmoczala@gmail.com" tar=
get=3D"_blank">mmoczala@gmail.com</a>&gt;</span>:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div class=3D"HOEnZb"><div class=3D"h5"><div dir=3D"ltr"><div>Hell=
o once again,</div><div><br></div><div>Please tell me what do you think abo=
ut the following example:</div><div><br></div><div><font face=3D"courier ne=
w, monospace">#include &lt;cstdio&gt;</font></div><div><font face=3D"courie=
r new, monospace">#include &lt;string&gt;</font></div><div><font face=3D"co=
urier new, monospace"><br></font></div><div><font face=3D"courier new, mono=
space">class LogFile</font></div><div><font face=3D"courier new, monospace"=
>{</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 pri=
vate:</font></div><div><font face=3D"courier new, monospace"><br></font></d=
iv><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 F=
ILE *file;</font></div><div><font face=3D"courier new, monospace"><br></fon=
t></div><div><font face=3D"courier new, monospace"><br></font></div><div><f=
ont face=3D"courier new, monospace">=C2=A0 =C2=A0 public:</font></div><div>=
<font face=3D"courier new, monospace"><br></font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 LogFile() :</font></div>=
<div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 file(NULL)</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new,=
 monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"co=
urier new, monospace"><br></font></div><div><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~LogFile()</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div>=
<font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 close();</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, mono=
space"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 void append(const char *fileName)</font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></di=
v><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 close();</font></div><div><font face=3D"courier new, monospac=
e">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D fopen(fileName, &quot=
;a+t&quot;);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospac=
e"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 void close()</font></div><div><font face=3D"courier new, =
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"cou=
rier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(file) {</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(file);</font></div><div><font fac=
e=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 file =3D NULL;</font></div><div><font face=3D"courier new, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><di=
v><font face=3D"courier new, monospace"><br></font></div><div><font face=3D=
"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 bool isOpened() const<=
/font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return file !=3D NULL;</font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></di=
v><div><font face=3D"courier new, monospace"><br></font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void write(const =
char *message)</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(file, &quot;%s\n&q=
uot;, message);</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, mono=
space">};</font></div><div><font face=3D"courier new, monospace"><br></font=
></div><div><font face=3D"courier new, monospace">class Log</font></div><di=
v><font face=3D"courier new, monospace">{</font></div><div><font color=3D"#=
0000ff" face=3D"courier new, monospace">=C2=A0 =C2=A0 private:</font></div>=
<div><font color=3D"#0000ff" face=3D"courier new, monospace"><br></font></d=
iv><div><font color=3D"#0000ff" face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 static LogFile logFile;</font></div><div><font color=3D"#=
0000ff" face=3D"courier new, monospace"><br></font></div><div><font color=
=3D"#0000ff" face=3D"courier new, monospace"><br></font></div><div><font co=
lor=3D"#0000ff" face=3D"courier new, monospace">=C2=A0 =C2=A0 public:</font=
></div><div><font color=3D"#0000ff" face=3D"courier new, monospace"><br></f=
ont></div><div><font color=3D"#0000ff" face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 static Log()</font></div><div><font color=3D"#0000=
ff" face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></d=
iv><div><font color=3D"#0000ff" face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.append(&quot;log.txt&quot;);</font>=
</div><div><font color=3D"#0000ff" face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(!logFile.isOpened())</font></div><div=
><font color=3D"#0000ff" face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &quot;ERROR: Failed =
to create &#39;log.txt&#39; file.\n&quot;);</font></div><div><font color=3D=
"#0000ff" face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</fo=
nt></div><div><font face=3D"courier new, monospace"><br></font></div><div><=
font face=3D"courier new, monospace"><br></font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 private:</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::string str;</font></div><div><fo=
nt face=3D"courier new, monospace"><br></font></div><div><font face=3D"cour=
ier new, monospace"><br></font></div><div><font face=3D"courier new, monosp=
ace">=C2=A0 =C2=A0 public:</font></div><div><font face=3D"courier new, mono=
space"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 ~Log()</font></div><div><font face=3D"courier new, mon=
ospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.write(s=
tr.c_str());</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospac=
e"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 void write(const char *text)</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div>=
<font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 if(str.length())</font></div><div><font face=3D"courier new, monospa=
ce">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D &quot;=
 =C2=A0 =C2=A0&quot;;</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D text;</font></div><div=
><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 str +=3D &#39;\n&#39;;</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"cour=
ier new, monospace">};</font></div><div><font face=3D"courier new, monospac=
e"><br></font></div><div><font face=3D"courier new, monospace">int main()</=
font></div><div><font face=3D"courier new, monospace">{</font></div><div><f=
ont face=3D"courier new, monospace">=C2=A0 =C2=A0 Log logAlpha, logNum;</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.=
write(&quot;A message&quot;);</font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 logNum.write(&quot;1 message&quot;);</font></div><d=
iv><font face=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.write(&quot=
;B message&quot;);</font></div><div><font face=3D"courier new, monospace">=
=C2=A0 =C2=A0 logNum.write(&quot;2 message&quot;);</font></div><div><font f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.write(&quot;C message=
&quot;);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 logNum.write(&quot;3 message&quot;);</font></div><div><font face=3D"cou=
rier new, monospace"><br></font></div><div><font face=3D"courier new, monos=
pace">=C2=A0 =C2=A0 return 0;</font></div><div><font face=3D"courier new, m=
onospace">}</font></div><div><br></div><div>OUTPUT:</div><div><br></div><di=
v><font face=3D"courier new, monospace">1 message</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 2 message</font></div><div><fon=
t face=3D"courier new, monospace">=C2=A0 =C2=A0 3 message</font></div><div>=
<font face=3D"courier new, monospace"><br></font></div><div><font face=3D"c=
ourier new, monospace">A message</font></div><div><font face=3D"courier new=
, monospace">=C2=A0 =C2=A0 B message</font></div><div><font face=3D"courier=
 new, monospace">=C2=A0 =C2=A0 C message</font></div><div><br></div><div>Re=
garding the code marked in <font color=3D"#0000ff">blue</font>:</div><div><=
ul><li>The static logFile variable is defined because a static class constr=
uctor is defined. The static variable can be also initialized through initi=
alizer list<br></li><li>The static class constructor is executed once, so y=
ou can perform actions like filie open<br></li><li>The static logFile varia=
ble will be destroyed on application termination as usual static variable<b=
r></li><li>Is this a kind of a singleton or not?<br></li></ul></div><div><b=
r></div><div>Many thanks,</div><div>Mariusz</div></div>

<p></p></div></div>

-- <br><span class=3D"">
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+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-494d-84c6-69c1ebbf8203%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/08b9502c-88bb-=
494d-84c6-69c1ebbf8203%40isocpp.org</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAKiZDp2%3DanO%2B7tasGDbOpLB-5_zGJotZ=
%3DNOnthxh-%3Dm3EUVYmQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKiZDp2%=
3DanO%2B7tasGDbOpLB-5_zGJotZ%3DNOnthxh-%3Dm3EUVYmQ%40mail.gmail.com</a>.<br=
 />

--001a114e30dc3fb82505388b4302--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 26 Jul 2016 08:21:14 -0700 (PDT)
Raw View
------=_Part_225_1778537806.1469546474513
Content-Type: multipart/alternative;
 boundary="----=_Part_226_1593690273.1469546474513"

------=_Part_226_1593690273.1469546474513
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=8E=D0=BB=D1=8F 201=
6 =D0=B3., 21:50:34 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> Hello once again,
>
> Please tell me what do you think about the following example:
>
> #include <cstdio>
> #include <string>
>
> class LogFile
> {
>     private:
>
>         FILE *file;
>
>
>     public:
>
>         LogFile() :
>             file(NULL)
>         {
>         }
>
>         ~LogFile()
>         {
>             close();
>         }
>
>         void append(const char *fileName)
>         {
>             close();
>             file =3D fopen(fileName, "a+t");
>         }
>
>         void close()
>         {
>             if(file) {
>                 fclose(file);
>                 file =3D NULL;
>             }
>         }
>
>         bool isOpened() const
>         {
>             return file !=3D NULL;
>         }
>
>         void write(const char *message)
>         {
>             fprintf(file, "%s\n", message);
>         }
> };
>
> class Log
> {
>     private:
>
>         static LogFile logFile;
>
>
>     public:
>
>         static Log()
>         {
>             logFile.append("log.txt");
>             if(!logFile.isOpened())
>                 fprintf(stderr, "ERROR: Failed to create 'log.txt'=20
> file.\n");
>         }
>
>
>     private:
>
>         std::string str;
>
>
>     public:
>
>         ~Log()
>         {
>             logFile.write(str.c_str());
>         }
>
>         void write(const char *text)
>         {
>             if(str.length())
>                 str +=3D "    ";
>             str +=3D text;
>             str +=3D '\n';
>         }
> };
>
> int main()
> {
>     Log logAlpha, logNum;
>     logAlpha.write("A message");
>     logNum.write("1 message");
>     logAlpha.write("B message");
>     logNum.write("2 message");
>     logAlpha.write("C message");
>     logNum.write("3 message");
>
>     return 0;
> }
>
> OUTPUT:
>
> 1 message
>     2 message
>     3 message
>
> A message
>     B message
>     C message
>
> Regarding the code marked in blue:
>
>    - The static logFile variable is defined because a static class=20
>    constructor is defined. The static variable can be also initialized th=
rough=20
>    initializer list
>    - The static class constructor is executed once, so you can perform=20
>    actions like filie open
>    - The static logFile variable will be destroyed on application=20
>    termination as usual static variable
>    - Is this a kind of a singleton or not?
>   =20
>
> Many thanks,
> Mariusz
>

Log example is bad because you do need static variable and want it to be=20
initialized before main this scenario is covered by constructor of your=20
static variable quite well. Plugin registration example is great because=20
nobody need any variable. The only thing required is some code to be=20
executed automatically but dummy unused variable is needed only because of=
=20
no way to execute it in a proper (non-hackish) way.

Sergey Vidyuk

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7eb116b0-78f8-4040-aafb-4dc81bf22ffe%40isocpp.or=
g.

------=_Part_226_1593690273.1469546474513
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=
=8E=D0=BB=D1=8F 2016 =D0=B3., 21:50:34 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala =D0=BD=D0=B0=D0=
=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>Hello once again,</div><div><br></div><div>Please tell =
me what do you think about the following example:</div><div><br></div><div>=
<font face=3D"courier new, monospace">#include &lt;cstdio&gt;</font></div><=
div><font face=3D"courier new, monospace">#include &lt;string&gt;</font></d=
iv><div><font face=3D"courier new, monospace"><br></font></div><div><font f=
ace=3D"courier new, monospace">class LogFile</font></div><div><font face=3D=
"courier new, monospace">{</font></div><div><font face=3D"courier new, mono=
space">=C2=A0 =C2=A0 private:</font></div><div><font face=3D"courier new, m=
onospace"><br></font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 FILE *file;</font></div><div><font face=3D"courier=
 new, monospace"><br></font></div><div><font face=3D"courier new, monospace=
"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0=
 public:</font></div><div><font face=3D"courier new, monospace"><br></font>=
</div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 LogFile() :</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file(NULL)</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><di=
v><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font=
></div><div><font face=3D"courier new, monospace"><br></font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~LogFile()</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=3D"cou=
rier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font f=
ace=3D"courier new, monospace"><br></font></div><div><font face=3D"courier =
new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void append(const char *fileNam=
e)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D =
fopen(fileName, &quot;a+t&quot;);</font></div><div><font face=3D"courier ne=
w, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"=
courier new, monospace"><br></font></div><div><font face=3D"courier new, mo=
nospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void close()</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><di=
v><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 if(file) {</font></div><div><font face=3D"courier new, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(file);</font=
></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D NULL;</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br></font>=
</div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 bool isOpened() const</font></div><div><font face=3D"courier new, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courier =
new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return file !=3D =
NULL;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br>=
</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 void write(const char *message)</font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
fprintf(file, &quot;%s\n&quot;, message);</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font =
face=3D"courier new, monospace">};</font></div><div><font face=3D"courier n=
ew, monospace"><br></font></div><div><font face=3D"courier new, monospace">=
class Log</font></div><div><font face=3D"courier new, monospace">{</font></=
div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 private:</font></div><div><font face=3D"courier new, monospace" color=
=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static LogFile logFile;</font><=
/div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></fon=
t></div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></=
font></div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=
=A0 =C2=A0 public:</font></div><div><font face=3D"courier new, monospace" c=
olor=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace=
" color=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static Log()</font></div><d=
iv><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace" colo=
r=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.append(&quo=
t;log.txt&quot;);</font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(!logFile.isOpe=
ned())</font></div><div><font face=3D"courier new, monospace" color=3D"#000=
0ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr=
, &quot;ERROR: Failed to create &#39;log.txt&#39; file.\n&quot;);</font></d=
iv><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace">=
<br></font></div><div><font face=3D"courier new, monospace"><br></font></di=
v><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 private:</font><=
/div><div><font face=3D"courier new, monospace"><br></font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::string st=
r;</font></div><div><font face=3D"courier new, monospace"><br></font></div>=
<div><font face=3D"courier new, monospace"><br></font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 public:</font></div><div><font fa=
ce=3D"courier new, monospace"><br></font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~Log()</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><di=
v><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 logFile.write(str.c_str());</font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void write(const char *text)</font></=
div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
{</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 if(str.length())</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 str +=3D &quot; =C2=A0 =C2=A0&quot;;</font></div><div><font face=3D"cou=
rier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D tex=
t;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D &#39;\n&#39;;</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div>=
<font face=3D"courier new, monospace">};</font></div><div><font face=3D"cou=
rier new, monospace"><br></font></div><div><font face=3D"courier new, monos=
pace">int main()</font></div><div><font face=3D"courier new, monospace">{</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 Log log=
Alpha, logNum;</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 logAlpha.write(&quot;A message&quot;);</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;1 message&qu=
ot;);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
logAlpha.write(&quot;B message&quot;);</font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;2 message&quot;);</font=
></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.wr=
ite(&quot;C message&quot;);</font></div><div><font face=3D"courier new, mon=
ospace">=C2=A0 =C2=A0 logNum.write(&quot;3 message&quot;);</font></div><div=
><font face=3D"courier new, monospace"><br></font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 return 0;</font></div><div><font face=
=3D"courier new, monospace">}</font></div><div><br></div><div>OUTPUT:</div>=
<div><br></div><div><font face=3D"courier new, monospace">1 message</font><=
/div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 2 message</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 3 message=
</font></div><div><font face=3D"courier new, monospace"><br></font></div><d=
iv><font face=3D"courier new, monospace">A message</font></div><div><font f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0 B message</font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 C message</font></div><div=
><br></div><div>Regarding the code marked in <font color=3D"#0000ff">blue</=
font>:</div><div><ul><li>The static logFile variable is defined because a s=
tatic class constructor is defined. The static variable can be also initial=
ized through initializer list<br></li><li>The static class constructor is e=
xecuted once, so you can perform actions like filie open<br></li><li>The st=
atic logFile variable will be destroyed on application termination as usual=
 static variable<br></li><li>Is this a kind of a singleton or not?<br></li>=
</ul></div><div><br></div><div>Many thanks,</div><div>Mariusz</div></div></=
blockquote><div><br>Log example is bad because you do need static variable =
and want it to be initialized before main this scenario is covered by const=
ructor of your static variable quite well. Plugin registration example is g=
reat because nobody need any variable. The only thing required is some code=
 to be executed automatically but dummy unused variable is needed only beca=
use of no way to execute it in a proper (non-hackish) way.<br><br>Sergey Vi=
dyuk<br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7eb116b0-78f8-4040-aafb-4dc81bf22ffe%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7eb116b0-78f8-4040-aafb-4dc81bf22ffe=
%40isocpp.org</a>.<br />

------=_Part_226_1593690273.1469546474513--

------=_Part_225_1778537806.1469546474513--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Tue, 26 Jul 2016 08:21:38 -0700 (PDT)
Raw View
------=_Part_200_1386054715.1469546498783
Content-Type: multipart/alternative;
 boundary="----=_Part_201_114150700.1469546498783"

------=_Part_201_114150700.1469546498783
Content-Type: text/plain; charset=UTF-8


>
> ... I fail to see the gains from the additional syntax, at least in C++
> (other languages like C# or Java gain from this, but they instantiate
> objects quite differently). What does it bring that we cannot already do
> with minimal effort?


Of course you can do it this way, but as I said before, you need to define
somewhere in cpp file this: Log::LogFileHandler Log::handler. Therefore it
will not work for header-only libraries.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bd4a92a0-f362-409b-b7fd-56c892035861%40isocpp.org.

------=_Part_201_114150700.1469546498783
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-c=
olor: rgb(204, 204, 204); padding-left: 1ex;">... I fail to see the gains f=
rom the additional syntax, at least in C++ (other languages like C# or Java=
 gain from this, but they instantiate objects quite differently). What does=
 it bring that we cannot already do with minimal effort?</blockquote><div><=
br></div><div>Of course you can do it this way, but as I said before, you n=
eed to define somewhere in cpp file this:=C2=A0Log::LogFileHandler Log::han=
dler. Therefore it will not work for header-only libraries.</div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bd4a92a0-f362-409b-b7fd-56c892035861%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bd4a92a0-f362-409b-b7fd-56c892035861=
%40isocpp.org</a>.<br />

------=_Part_201_114150700.1469546498783--

------=_Part_200_1386054715.1469546498783--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 26 Jul 2016 08:26:06 -0700 (PDT)
Raw View
------=_Part_211_2105186307.1469546766522
Content-Type: multipart/alternative;
 boundary="----=_Part_212_724562612.1469546766522"

------=_Part_212_724562612.1469546766522
Content-Type: text/plain; charset=UTF-8


>
>
> ... I fail to see the gains from the additional syntax, at least in C++
> (other languages like C# or Java gain from this, but they instantiate
> objects quite differently). What does it bring that we cannot already do
> with minimal effort?
>
>
It allows to tweek language in the future to make existing Link Time
Optimisations which elliminate unused static variables and their
constructors standard complying. Those kind of optimisations are extremely
usfull to shrink final executable and improve startup time when using huge
frameworks.

Sergey Vidyuk

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5315f30d-9e22-4555-80c7-173020c617ff%40isocpp.org.

------=_Part_212_724562612.1469546766522
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br></div>... I fail to see the gains from the additional syntax, =
at least in C++ (other languages like C# or Java gain from this, but they i=
nstantiate objects quite differently). What does it bring that we cannot al=
ready do with minimal effort?<br><div><br></div></div></blockquote><div><br=
>It allows to tweek language in the future to make existing Link Time Optim=
isations which elliminate unused static variables and their constructors st=
andard complying. Those kind of optimisations are extremely usfull to shrin=
k final executable and improve startup time when using huge frameworks.<br>=
<br>Sergey Vidyuk <br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5315f30d-9e22-4555-80c7-173020c617ff%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5315f30d-9e22-4555-80c7-173020c617ff=
%40isocpp.org</a>.<br />

------=_Part_212_724562612.1469546766522--

------=_Part_211_2105186307.1469546766522--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 26 Jul 2016 08:28:55 -0700 (PDT)
Raw View
------=_Part_519_680159964.1469546935293
Content-Type: multipart/alternative;
 boundary="----=_Part_520_2005076932.1469546935293"

------=_Part_520_2005076932.1469546935293
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=8E=D0=BB=D1=8F 201=
6 =D0=B3., 22:21:39 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> ... I fail to see the gains from the additional syntax, at least in C++=
=20
>> (other languages like C# or Java gain from this, but they instantiate=20
>> objects quite differently). What does it bring that we cannot already do=
=20
>> with minimal effort?
>
>
> Of course you can do it this way, but as I said before, you need to defin=
e=20
> somewhere in cpp file this: Log::LogFileHandler Log::handler. Therefore i=
t=20
> will not work for header-only libraries.
>

inline variables are going to solve this issue. Using static class=20
constructor initialize static variable is the same type of hack as using=20
dummy unused variable to execute some library initialization code :)

Sergey Vidyuk

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1dd81be4-00c0-450d-ab5f-3761063a00a8%40isocpp.or=
g.

------=_Part_520_2005076932.1469546935293
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=
=8E=D0=BB=D1=8F 2016 =D0=B3., 22:21:39 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala =D0=BD=D0=B0=D0=
=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb=
(204,204,204);padding-left:1ex">... I fail to see the gains from the additi=
onal syntax, at least in C++ (other languages like C# or Java gain from thi=
s, but they instantiate objects quite differently). What does it bring that=
 we cannot already do with minimal effort?</blockquote><div><br></div><div>=
Of course you can do it this way, but as I said before, you need to define =
somewhere in cpp file this:=C2=A0Log::LogFileHandler Log::handler. Therefor=
e it will not work for header-only libraries.</div></div></blockquote><div>=
<br>inline variables are going to solve this issue. Using static class cons=
tructor initialize static variable is the same type of hack as using dummy =
unused variable to execute some library initialization code :)<br><br>Serge=
y Vidyuk<br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1dd81be4-00c0-450d-ab5f-3761063a00a8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1dd81be4-00c0-450d-ab5f-3761063a00a8=
%40isocpp.org</a>.<br />

------=_Part_520_2005076932.1469546935293--

------=_Part_519_680159964.1469546935293--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Tue, 26 Jul 2016 08:37:34 -0700 (PDT)
Raw View
------=_Part_592_1159331704.1469547454338
Content-Type: multipart/alternative;
 boundary="----=_Part_593_1053995877.1469547454338"

------=_Part_593_1053995877.1469547454338
Content-Type: text/plain; charset=UTF-8


>
> inline variables are going to solve this issue. Using static class
> constructor initialize static variable is the same type of hack as using
> dummy unused variable to execute some library initialization code :)


Does static inline variables allow to do something like this?

static MyClass() :
  staticMember1(123, 456),
  staticMember2("example"),
  staticMember3(staticMember1, staticMember2)
{
}

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/932fd7de-dc8d-4686-8541-0d4a4e530233%40isocpp.org.

------=_Part_593_1053995877.1469547454338
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"border-left-wid=
th: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); p=
adding-left: 1ex;">inline variables are going to solve this issue. Using st=
atic class constructor initialize static variable is the same type of hack =
as using dummy unused variable to execute some library initialization code =
:)</blockquote><div><br></div><div>Does static inline variables allow to do=
 something like this?</div><div><br></div><div><font face=3D"courier new, m=
onospace">static MyClass() :</font></div><font face=3D"courier new, monospa=
ce">=C2=A0 staticMember1(123, 456),</font><div><font face=3D"courier new, m=
onospace">=C2=A0 staticMember2(&quot;example&quot;),</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 staticMember3(staticMember1, static=
Member2)</font></div><div><font face=3D"courier new, monospace">{</font></d=
iv><div><font face=3D"courier new, monospace">}</font></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/932fd7de-dc8d-4686-8541-0d4a4e530233%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/932fd7de-dc8d-4686-8541-0d4a4e530233=
%40isocpp.org</a>.<br />

------=_Part_593_1053995877.1469547454338--

------=_Part_592_1159331704.1469547454338--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 26 Jul 2016 08:45:03 -0700 (PDT)
Raw View
------=_Part_275_980310824.1469547903107
Content-Type: multipart/alternative;
 boundary="----=_Part_276_916565383.1469547903107"

------=_Part_276_916565383.1469547903107
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=8E=D0=BB=D1=8F 201=
6 =D0=B3., 22:37:34 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> inline variables are going to solve this issue. Using static class=20
>> constructor initialize static variable is the same type of hack as using=
=20
>> dummy unused variable to execute some library initialization code :)
>
>
> Does static inline variables allow to do something like this?
>
> static MyClass() :
>   staticMember1(123, 456),
>   staticMember2("example"),
>   staticMember3(staticMember1, staticMember2)
> {
> }
>

It's better to check proposal wording in order to get the answer. But from=
=20
my personal point of view it should be done by allowing static class=20
members to be inline variables and the main reason to add static=20
constructors should be ability to execute some initialization code whose=20
desired side effect is not related to any static variable initialization.

Sergey

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/91fd0679-fdc9-4266-af20-eeb1b354d88e%40isocpp.or=
g.

------=_Part_276_916565383.1469547903107
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 26 =D0=B8=D1=
=8E=D0=BB=D1=8F 2016 =D0=B3., 22:37:34 UTC+7 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=
=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Mariusz Moczala =D0=BD=D0=B0=D0=
=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"border-left-width=
:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-lef=
t:1ex">inline variables are going to solve this issue. Using static class c=
onstructor initialize static variable is the same type of hack as using dum=
my unused variable to execute some library initialization code :)</blockquo=
te><div><br></div><div>Does static inline variables allow to do something l=
ike this?</div><div><br></div><div><font face=3D"courier new, monospace">st=
atic MyClass() :</font></div><font face=3D"courier new, monospace">=C2=A0 s=
taticMember1(123, 456),</font><div><font face=3D"courier new, monospace">=
=C2=A0 staticMember2(&quot;example&quot;),</font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 staticMember3(staticMember1, staticMember2)</=
font></div><div><font face=3D"courier new, monospace">{</font></div><div><f=
ont face=3D"courier new, monospace">}</font></div></div></blockquote><div><=
br>It&#39;s better to check proposal wording in order to get the answer. Bu=
t from my personal point of view it should be done by allowing static class=
 members to be inline variables and the main reason to add static construct=
ors should be ability to execute some initialization code whose desired sid=
e effect is not related to any static variable initialization.<br><br>Serge=
y<br></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/91fd0679-fdc9-4266-af20-eeb1b354d88e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/91fd0679-fdc9-4266-af20-eeb1b354d88e=
%40isocpp.org</a>.<br />

------=_Part_276_916565383.1469547903107--

------=_Part_275_980310824.1469547903107--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Thu, 28 Jul 2016 07:18:24 -0700 (PDT)
Raw View
------=_Part_6038_1044893707.1469715504926
Content-Type: multipart/alternative;
 boundary="----=_Part_6039_116453289.1469715504926"

------=_Part_6039_116453289.1469715504926
Content-Type: text/plain; charset=UTF-8

Hello everyone!

Thank you very much for all extremely valuable comments.
I tried to cover all in the attached proposal.

I will be very grateful if you have any further comments and suggestions.

Thanks,
Matiusz

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5d8f55fa-ff28-4fb2-8e23-90715b7e13fc%40isocpp.org.

------=_Part_6039_116453289.1469715504926
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello everyone!<div><br></div><div>Thank you very much for=
 all extremely valuable comments.</div><div>I tried to cover all in the att=
ached proposal.</div><div><br></div><div>I will be very grateful if you hav=
e any further comments and suggestions.</div><div><br></div><div>Thanks,</d=
iv><div>Matiusz</div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5d8f55fa-ff28-4fb2-8e23-90715b7e13fc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5d8f55fa-ff28-4fb2-8e23-90715b7e13fc=
%40isocpp.org</a>.<br />

------=_Part_6039_116453289.1469715504926--

------=_Part_6038_1044893707.1469715504926
Content-Type: text/html; charset=US-ASCII;
 name="static class constructor.htm"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="static class constructor.htm"
X-Attachment-Id: 6ea1a4ab-6a62-46c4-a53a-eac71333767a
Content-ID: <6ea1a4ab-6a62-46c4-a53a-eac71333767a>

<p>Document Number: D0421R0<br />
Audience: Evolution Working Group (EWG)<br />
Mariusz Moczala &lt;<a href="mailto:mmoczala@gmail.com">mmoczala@gmail.com</a>&gt;<br />
Date: 2016-07-24</p>

<h1>Static class constructor</h1>

<h2>1. Content</h2>
<p>1. Content<br />
2. Abstract<br />
3. Motivation<br />
4. Impact On the Standard<br />
5. Design Decisions<br />
5.1. Declaration and definition<br />
5.2. Initializer list and parameters<br />
5.3. Execution order (global and inheritance)<br />
5.4. One Definition Rule<br />
5.5. Linking<br />
5.6. Local classes<br />
5.7. Static destructor<br />
6. Example application<br />
7. References</p>

<h2>2. Abstract</h2>
<p>As a class constructor is dedicated for object initialization, the proposed static class constructor offers type registration. The static class constructor is called once for each class, early before main() function execution. As usual static function, the static class constructor have no associated object.</p>

<h2>3. Motivation</h2>
<p>Static class constructor has been proposed to execute class initialization code whose effect is not related to any static variable initialization. It has been found that it may also offer:</p>
<p><ul>
<li>consistent mechanism for type registration</li>
<li>static member initialization in more convenient way</li>
<li>enabling application functionality without using preprocessor</li>
<li>execution of class initialization code without using dummy global variable</li>
</ul></p>

<h2>4. Impact On the Standard</h2>
<p>This proposal adds new language feature which affects compiler, linker and program startup code.</p>
<p>The feature is backward compatible as classes does not has to provide a definition of static class constructor. When class defines a static class constructor, used syntax is identical with definition of default class constructor, except that the static class constructor name is preceded by static keyword.</p>
<p>Static class constructor is called once for each class in the same manner as constructors of objects defined at global scope and always before executing main() function. Linker must then generate list of all static class constructors, to be executed by program startup code.</p>
<p>Static class variables can be initialized on member initializer list of static class constructor. Therefore, when single header is used for multiple translation units, One Definition Rule must be meet.</p>
<p>When library code is never used in program but provides a static class constructors, the library code must be incorporated in executable to offer a way for application and library integration without additional programmer interaction.</p>

<h2>5. Design Decisions</h2>
<p>For better clarification, please consider the following code using a static class constructor:</p>
<pre>class MyPlugin : public Plugin {
  public:
    static MyPlugin() {
      static MyPlugin myPlugin;
      Plugins::registerPlugin(&amp;myPlugin);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
};</pre>
<p>Which is equivalent to the following, defined at global scope:</p>
<pre>class MyPlugin : public Plugin {
  public:
    MyPlugin() {
      Plugins::registerPlugin(this);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
} myPlugin;</pre>
<p>Nevertheless, the equivalent code have some pitfalls which can be avoided with static class constructor:</p>
<p><ul>
<li>There is no need to create dummy global variable to perform initialization.</li>
<li>Each dummy global variable used in initialization have associated identifier and therefore is visible under IntelliSense. It becomes difficult in navigation, when multiple dummy global variables are defined.</li>
<li>Static constructors allows to perform early initialization for headers-only libraries, where global variables cannot be used.</li>
</ul></p>

<h3>5.1. Declaration and definition</h3>
<p>Class does not have to provide a declaration nor definition of static class constructor. When class defines a static class constructor, used syntax is identical with definition of default class constructor, except that the static class constructor name is preceded by static keyword in declaration. Only one static class constructor can be defined for a class.</p>

<h3>5.2. Initializer list and parameters</h3>
<p>The static class constructor is called once by program startup code and cannot be executed manually. Therefore it does not take any arguments as in case of class destructor.</p>
<p>The static class constructor is a good place to provide initialization of static class members. It can be done through initializers list as for non-static class member initialization on non-static class constructor.</p>

<h3>5.3. This pointer</h3>
<p>The static class constructor is not associated with an object as other static class functions. Therefore this pointer is not available for static class constructors.</p>

<h3>5.4. Execution order (global and inheritance)</h3>
<p>Static class constructors are executed one by one among execution of class constructors for variables defined at global scope.</p>

<h3>5.5. One Definition Rule</h3>
<p>Static class variables can be initialized on member initializer list of static class constructor. Therefore, when single header is used for multiple translation units, One Definition Rule must be meet.</p>

<h3>5.6. Linking</h3>
<p>When library code is never used in program but provides a static class constructors, the library code must be incorporated in executable to offer a way for application and library integration without additional programmer interaction.</p>

<h3>5.7. Local classes</h3>
<p>There is no distinction between static class constructors defined for classes at global and local scope.</p>

<h3>5.8. Static class destructor</h3>
<p>A static class destructor was also considered on early proposal stage. It could work in similar way to static class constructor, but to perform type deregistration. It has been found that introducing such functionality can be simply replaced with classical destructor, as static class constructor allow to create a static object, which will be destroyed on process termination.</p>
<p>Nevertheless it would be useful to have a static class destructor along with static class constructor, as it may open new possibilities which are not so obvious at the time when this document was created.</p>

<h3>6. Static inline variables</h3>
<p>Proposed static class constructor offers similar features to static inline variables proposed for C++17 standard. However both proposals are not excluding each other. As static inline variables souds reasonable fo static class member initialization, achieving early initialization functionality through static inline variables is more difficult and have more complicated syntax. In this case static class constructor is more reasonable.</p>

<h3>7. References</h3>
<p><ul>
<li>Bjarne Stroustrup, The C++ Programming Language 3rd edition, 1997, Addison Wesley ISBN 0-201-88954-4 p496</li>
<li>One Definition Rule</li>
<li>Static inline variable: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf</li>
<li>JSF AV C++ Std => page 21; AV rule 31</li>
</ul></p>

------=_Part_6038_1044893707.1469715504926--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 28 Jul 2016 11:04:54 -0700
Raw View
On quinta-feira, 28 de julho de 2016 07:18:24 PDT Mariusz Moczala wrote:
> Static class constructor is called once for each class in the same manner as
> constructors of objects defined at global scope and always before executing
> main() function. Linker must then generate list of all static class
> constructors, to be executed by program startup code.

Please explain how the list is created and advise how ABIs should deal with
this in case of shared libraries and that of static libraries.

Assume you can't modify the linker.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1539417.I4opRRii1G%40tjmaciei-mobl1.

.


Author: szollosi.lorand@gmail.com
Date: Fri, 29 Jul 2016 02:17:27 -0700 (PDT)
Raw View
------=_Part_288_1675279345.1469783847157
Content-Type: multipart/alternative;
 boundary="----=_Part_289_1083866000.1469783847158"

------=_Part_289_1083866000.1469783847158
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

I do see some issues / mentionable comments:

   - You declare static constructors as if they had a return type of the=20
   class type: *static MyClass() { ... };*, which I think is inconsistent=
=20
   with current C++ grammar. Note that in the position where you've put=20
   *MyClass*, we usually put (loosely speaking) return type. This includes=
=20
   the (non-static) constructor(s), which evaluate to *MyClass *and have no=
=20
   name. Possible fixes for this include *static void() { ... };* and *stat=
ic=20
   void MyClass() { ... };*, the second being a clash on a typical error=20
   that is usually reported separately by the compiler. Or you might use a=
=20
   single name for all types, e.g. *static void constructor() { ... };*.
   - However, if your constructor really returns void, how will you handle=
=20
   errors? Normally constructors are either exception-safe (read: we ignore=
=20
   some exceptions that we want to fail early for) or report error by=20
   *throw*ing something. Having a *static int constructor_error_code*=20
   doesn't really help if the constructor doesn't execute fully.
   - Your document requires linker support. That goes way beyond C++: even=
=20
   if we standardized static constructors, if you require linkers to be=20
   changed, then it's perhaps the best to first ask linkers to allow for th=
is.=20
   This is a dependency for compiler implementers.
   - What about DLL / .so files? It's already kind of a nightmare to have=
=20
   static initialization there. These would need very clear recipes to have=
=20
   them defect free.
   - Correct me if I'm wrong, it'll need at least a *static bool* per class=
=20
   to know it it's been initialized as two libs might have the same class. =
In=20
   that case, it's just a syntax sugar over *static bool constructor_result=
=20
   =3D []{ ... }();*
   - I suggest underlining (and explaining why is) that, unlike default=20
   constructors, they're not auto-generated if missing. Having a *static=20
   bool* (non-const) for each template class I instantiate would make me=20
   invest in memory modules.
   - Which brings us to... can't these be unified? As a workaround for some=
=20
   static init issues, we used to have something like (feel free to laugh):


class MyClass
{
    //...

public:
    void deps()
    {
        DEPS(); // somewhere in the early headers you'll have #define=20
DEPS() []{}()
        #undef DEPS
        #define DEPS() MyClass::deps()
        static bool ready =3D false;
        if(!ready)
        {
            // actual 'static constructor' code
        }
    }
};


   - Terrible as it seems, it actually fixes all the ordering issues re:=20
      dependencies, inheritance, multi-init; it can be run from *main()* or=
=20
      *DllMain()* by a simple *DEPS();*, in which case it runs after static=
=20
      initializers. You might take this and modify to your needs when you w=
ant to=20
      specify the as-if of static ctor implementation. You might want to ex=
pose=20
      *ready* (or drop it if you wish) and make tha call to *DEPS(); *in=20
      *main()*-like functions automatic.
   - You're okay to allocate one byte per class for static destructors, but=
=20
   didn't seem okay to allocate one bit per class for static constructor? W=
hy=20
   is that? Or is there something I'm missing?
   - Technical details:
      - do you want static constructors to be (manually) callable?
      - do you want to be able to take their address?
      - does it make sense to have static constructors with parameters (and=
=20
      if yes, who would fill them: OS passing *argc, argv[]* or base /=20
      descendant, anyone else?)
      - is there a way to inherit static ctors? (e.g. *AbstractPlugin*=20
      comes to mind) If yes, how do we get current (most derived) type?
      - do you need static construction to be sequential, or just=20
      base-before-descendant? allowing for, but not requiring parallel=20
      initialization might speed up start-up without putting a burden on=20
      compilers.
      - can you instantiate _other_ classes during static construction?=20
      it's possible that their static ctor is not yet run, or that you have=
 an=20
      inter-dependency.
      - are vtables constructed by the time constructors are run?
      - can you initialize static (const) reference members and what's the=
=20
      syntax?
      - can you *throw* an object that's class is being statically=20
      constructed?
     =20
It's possible that some of these I should've found between the lines, in=20
which case I'm sorry. It's also totally ok to state that most of these=20
should remain UB.


Thanks,

-lorro


2016. j=C3=BAlius 28., cs=C3=BCt=C3=B6rt=C3=B6k 16:18:25 UTC+2 id=C5=91pont=
ban Mariusz Moczala a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> Hello everyone!
>
> Thank you very much for all extremely valuable comments.
> I tried to cover all in the attached proposal.
>
> I will be very grateful if you have any further comments and suggestions.
>
> Thanks,
> Matiusz
>

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7548eca4-cc70-455b-87f5-d49e6178e8cc%40isocpp.or=
g.

------=_Part_289_1083866000.1469783847158
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>I do see some issues / mentionable comments:<br=
><ul><li>You declare static constructors as if they had a return type of th=
e class type: <i>static MyClass() { ... };</i>, which I think is inconsiste=
nt with current C++ grammar. Note that in the position where you&#39;ve put=
 <i>MyClass</i>, we usually put (loosely speaking) return type. This includ=
es the (non-static) constructor(s), which evaluate to <i>MyClass </i>and ha=
ve no name. Possible fixes for this include <i>static void() { ... };</i> a=
nd <i>static void MyClass() { ... };</i>, the second being a clash on a typ=
ical error that is usually reported separately by the compiler. Or you migh=
t use a single name for all types, e.g. <i>static void constructor() { ... =
};</i>.</li><li>However, if your constructor really returns void, how will =
you handle errors? Normally constructors are either exception-safe (read: w=
e ignore some exceptions that we want to fail early for) or report error by=
 <i>throw</i>ing something. Having a <i>static int constructor_error_code</=
i> doesn&#39;t really help if the constructor doesn&#39;t execute fully.<br=
></li><li>Your document requires linker support. That goes way beyond C++: =
even if we standardized static constructors, if you require linkers to be c=
hanged, then it&#39;s perhaps the best to first ask linkers to allow for th=
is. This is a dependency for compiler implementers.<br></li><li>What about =
DLL / .so files? It&#39;s already kind of a nightmare to have static initia=
lization there. These would need very clear recipes to have them defect fre=
e.</li><li>Correct me if I&#39;m wrong, it&#39;ll need at least a <i>static=
 bool</i> per class to know it it&#39;s been initialized as two libs might =
have the same class. In that case, it&#39;s just a syntax sugar over <i>sta=
tic bool constructor_result =3D []{ ... }();</i></li><li>I suggest underlin=
ing (and explaining why is) that, unlike default constructors, they&#39;re =
not auto-generated if missing. Having a <i>static bool</i> (non-const) for =
each template class I instantiate would make me invest in memory modules.<b=
r></li><li>Which brings us to... can&#39;t these be unified? As a workaroun=
d for some static init issues, we used to have something like (feel free to=
 laugh<code>):</code></li></ul><p><br></p><p></p><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">MyClass</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">//...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">public</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> d=
eps</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 DEPS</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// s=
omewhere in the early headers you&#39;ll have #define DEPS() []{}()</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">#undef</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 DEPS<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">#define</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> DEPS</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">MyClass</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">deps</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> ready </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">false</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">if</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(!</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">ready</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// actual=
 &#39;static constructor&#39; code</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div><br><p></p><ul><ul><l=
i>Terrible as it seems, it actually fixes all the ordering issues re: depen=
dencies, inheritance, multi-init; it can be run from <i>main()</i> or <i>Dl=
lMain()</i> by a simple <i>DEPS();</i>, in which case it runs after static =
initializers. You might take this and modify to your needs when you want to=
 specify the as-if of static ctor implementation. You might want to expose =
<i>ready</i> (or drop it if you wish) and make tha call to <i>DEPS(); </i>i=
n <i>main()</i>-like functions automatic.</li></ul><li>You&#39;re okay to a=
llocate one byte per class for static destructors, but didn&#39;t seem okay=
 to allocate one bit per class for static constructor? Why is that? Or is t=
here something I&#39;m missing?</li><li>Technical details:</li><ul><li>do y=
ou want static constructors to be (manually) callable?</li><li>do you want =
to be able to take their address?</li><li>does it make sense to have static=
 constructors with parameters (and if yes, who would fill them: OS passing =
<i>argc, argv[]</i> or base / descendant, anyone else?)</li><li>is there a =
way to inherit static ctors? (e.g. <i>AbstractPlugin</i> comes to mind) If =
yes, how do we get current (most derived) type?</li><li>do you need static =
construction to be sequential, or just base-before-descendant? allowing for=
, but not requiring parallel initialization might speed up start-up without=
 putting a burden on compilers.<br></li><li>can you instantiate _other_ cla=
sses during static construction? it&#39;s possible that their static ctor i=
s not yet run, or that you have an inter-dependency.</li><li>are vtables co=
nstructed by the time constructors are run?<br></li><li>can you initialize<=
i> </i>static (const) reference members and what&#39;s the syntax?</li><li>=
can you <i>throw</i> an object that&#39;s class is being statically constru=
cted?<br></li></ul></ul><p>It&#39;s possible that some of these I should&#3=
9;ve found between the lines, in which case I&#39;m sorry. It&#39;s also to=
tally ok to state that most of these should remain UB.<br></p><p><br></p><p=
>Thanks,</p><p>-lorro<br></p><p><br></p>2016. j=C3=BAlius 28., cs=C3=BCt=C3=
=B6rt=C3=B6k 16:18:25 UTC+2 id=C5=91pontban Mariusz Moczala a k=C3=B6vetkez=
=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">Hello everyone!<div><br></div><div>Thank you very much for all extreme=
ly valuable comments.</div><div>I tried to cover all in the attached propos=
al.</div><div><br></div><div>I will be very grateful if you have any furthe=
r comments and suggestions.</div><div><br></div><div>Thanks,</div><div>Mati=
usz</div></div></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7548eca4-cc70-455b-87f5-d49e6178e8cc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7548eca4-cc70-455b-87f5-d49e6178e8cc=
%40isocpp.org</a>.<br />

------=_Part_289_1083866000.1469783847158--

------=_Part_288_1675279345.1469783847157--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Sat, 27 Aug 2016 10:14:54 -0700 (PDT)
Raw View
------=_Part_2695_385220036.1472318094907
Content-Type: multipart/alternative;
 boundary="----=_Part_2696_780331532.1472318094908"

------=_Part_2696_780331532.1472318094908
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



Hi,


Thank you very much for all invaluable comments!

Updated draft document D0421R1 has been attached.


Please explain how the list is created and advise how ABIs should deal with=
=20
this in case of shared libraries and that of static libraries. Assume you=
=20
can't modify the linker.

Good hint. I have modified it in the document. Thanks. The static class=20
constructor, is now behaving exactly the same as a default class=20
constructor of global variable, except have no associated object. Therefore=
=20
the same mechanism can be used to execute it with NULL instead of object=20
pointer. This does not requires to modify linker.

=20

You declare static constructors as if they had a return type of the class=
=20
type: static MyClass() { ... };, which I think is inconsistent with current=
=20
C++ grammar. Note that in the position where you've put MyClass, we usually=
=20
put (loosely speaking) return type. This includes the (non-static)=20
constructor(s), which evaluate to MyClass and have no name. Possible fixes=
=20
for this include static void() { ... }; and static void MyClass() { ... };,=
=20
the second being a clash on a typical error that is usually reported=20
separately by the compiler. Or you might use a single name for all types,=
=20
e.g. static void constructor() { ... };.

I see your point, but you cannot declare function with no name, so if the=
=20
function returns MyClass it will be: [static] MyClass identifier(=E2=80=A6)=
; but in=20
case of default/static class constructor, you have no such problem, because=
=20
MyClass is always followed by parenthesis and constructors have no returned=
=20
type. Then we have no ambiguity here. Did I properly understood your=20
comment?

=20

However, if your constructor really returns void, how will you handle=20
errors? Normally constructors are either exception-safe (read: we ignore=20
some exceptions that we want to fail early for) or report error by throwing=
=20
something. Having a static int constructor_error_code doesn't really help=
=20
if the constructor doesn't execute fully.

I am not sure about this. Your static int variable if declared in global=20
scope will be initialized before static class constructor is executed. You=
=20
can then use it to mark failure initially and set it to successful just=20
before returning from constructors code. The exceptions are working as in=
=20
case of default class constructor for global variables, so will have=20
similar problems here.

=20

Your document requires linker support. That goes way beyond C++: even if we=
=20
standardized static constructors, if you require linkers to be changed,=20
then it's perhaps the best to first ask linkers to allow for this. This is=
=20
a dependency for compiler implementers.

I modified the document to avoid linker modification. The static class=20
constructors uses now the same execution mechanism as for constructors of=
=20
global object.

=20

What about DLL / .so files? It's already kind of a nightmare to have static=
=20
initialization there. These would need very clear recipes to have them=20
defect free.

It would be very nice to have such functionality finally working in C++.=20
Nevertheless as linker cannot be modified, I am not addressing it anymore=
=20
in the document. I=E2=80=99ll try to issue another document to cover this p=
roblem=20
regarding both static class constructor and global variable initialization.

=20

Correct me if I'm wrong, it'll need at least a static bool per class to=20
know it it's been initialized as two libs might have the same class. In=20
that case, it's just a syntax sugar over static bool constructor_result =3D=
=20
[]{ ... }()

Could you please explain it a little bit more? When you would like to use=
=20
this static bool with lambda? I do know it is used to execute code once,=20
but how is this related? The lambda will not be called if object is not=20
created unlike the static class constructor.

=20

Having a static bool (non-const) for each template class I instantiate=20
would make me invest in memory modules.

I do not think this static bool is anywhere needed as it can be determined=
=20
once on program linking stage.

=20

I suggest underlining (and explaining why is) that, unlike default=20
constructors, they're not auto-generated if missing.

Good hint, I=E2=80=99ll cover it. Thanks. Actually we cannot say they are=
=20
auto-generated if missing. The static class constructor can initialize=20
static class members through initializer list as non-static members are=20
initialized through class constructor. However, if you have no default=20
constructor, members are initialized with its default constructor. We=20
cannot achieve this static class constructor, just to be backward=20
compatible. If you have no static class constructor, you must define the=20
static member outside the class body as usual. When static class=20
constructor is defined, all static members not defined on initializer list=
=20
will be initialized with its default constructor, even if they are not=20
defined outside the class body. So the backward compatibility is the reason=
..

=20

Which brings us to... can't these be unified? As a workaround for some=20
static init issues, we used to have something like (feel free to laugh):=20
[=E2=80=A6] Terrible as it seems, it actually fixes all the ordering issues=
 re:=20
dependencies, inheritance, multi-init; it can be run from main() or=20
DllMain() by a simple DEPS();, in which case it runs after static=20
initializer. You might take this and modify to your needs when you want to=
=20
specify the as-if of static ctor implementation. You might want to expose=
=20
ready (or drop it if you wish) and make tha call to DEPS(); in main()-like=
=20
functions automatic.

Interesting. Assuming void deps() is also static. In your code you have a=
=20
chain of execution, but each class depend (indirectly) on the other.=20
Moreover DEPS is in a single translation unit only. Additionally, the more=
=20
calls you have, the more stack you use. IMHO it is better/safer to build a=
=20
list (array) of pointers to functions and then execute it one by one.=20
However definitely the best way qould be tu use the static class=20
constructor, which provides more OOP way to do this.

=20

You're okay to allocate one byte per class for static destructors, but=20
didn't seem okay to allocate one bit per class for static constructor? Why=
=20
is that? Or is there something I'm missing?

Where I stated that? No additional allocations are needed. In the above=20
example with MyPlugin, static object was used to simplify the example.=20
However, of course depending on compiler configuration, empty class can=20
have a zero-length.

=20

do you want static constructors to be (manually) callable?

No, this feature is not available. It was already covered in document.

=20

do you want to be able to take their address?

No, there is no way to do this.

=20

does it make sense to have static constructors with parameters (and if yes,=
=20
who would fill them: OS passing argc, argv[] or base / descendant, anyone=
=20
else?)

No, you cannot pass parameters to the static class constructor. It was=20
already covered in document.

=20

is there a way to inherit static ctors? (e.g. AbstractPlugin comes to mind)=
=20
If yes, how do we get current (most derived) type?

Yes. Thank you for pointing that as I forgotten to cover it in the=20
document. Static class constructors are executed/inherited in the same=20
manner as default constructors.

=20

do you need static construction to be sequential, or just=20
base-before-descendant? allowing for, but not requiring parallel=20
initialization might speed up start-up without putting a burden on=20
compilers.

Sequential approach seems to be the most appropriate and as above=20
mentioned, the static class constructor of base class will be executed=20
first, then are initialized static members defined (and not defined)=20
 through the initializer list. Finally the code of static class constructor=
=20
is executed.

=20

can you instantiate _other_ classes during static construction? it's=20
possible that their static ctor is not yet run, or that you have an=20
inter-dependency.

You can instantiate classes and their static class constructors will be=20
executed before, same as global variables are initialized. The=20
initialization is performed in definition order within single translation=
=20
unit. Compare its behavior to class constructor execution of global=20
variables.

=20

are vtables constructed by the time constructors are run?

vtables are generated before; as for class constructor of global variables.

=20

can you initialize static (const) reference members and what's the syntax?

Hm, actually why not through initializers list? Any objection?

=20

can you throw an object that's class is being statically constructed?

I am thinking about this use case, but I do not see your point. Can you=20
elaborate a little bit more please?


Best Regards,

Mariusz

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ef622675-478b-4cf3-a9a6-d28433553f27%40isocpp.or=
g.

------=_Part_2696_780331532.1472318094908
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"co=
lor: rgb(0, 112, 192); background-image: initial; background-attachment: in=
itial; background-size: initial; background-origin: initial; background-cli=
p: initial; background-position: initial; background-repeat: initial;"><spa=
n style=3D"color: rgb(34, 34, 34);">Hi,</span></span></p><p class=3D"MsoNoS=
pacing"><span lang=3D"EN-US" style=3D"color: rgb(0, 112, 192); background-i=
mage: initial; background-attachment: initial; background-size: initial; ba=
ckground-origin: initial; background-clip: initial; background-position: in=
itial; background-repeat: initial;"><span style=3D"color: rgb(34, 34, 34);"=
><br></span></span></p><p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=
=3D"color: rgb(0, 112, 192); background-image: initial; background-attachme=
nt: initial; background-size: initial; background-origin: initial; backgrou=
nd-clip: initial; background-position: initial; background-repeat: initial;=
"><span style=3D"color: rgb(34, 34, 34);">Thank you very much for all inval=
uable comments!</span></span></p><p class=3D"MsoNoSpacing"><span lang=3D"EN=
-US" style=3D"background-image: initial; background-attachment: initial; ba=
ckground-size: initial; background-origin: initial; background-clip: initia=
l; background-position: initial; background-repeat: initial;">Updated draft=
 document=C2=A0D0421R1=C2=A0has been attached.</span></p><p class=3D"MsoNoS=
pacing"><span lang=3D"EN-US" style=3D"color: rgb(0, 112, 192); background-i=
mage: initial; background-attachment: initial; background-size: initial; ba=
ckground-origin: initial; background-clip: initial; background-position: in=
itial; background-repeat: initial;"><span style=3D"color: rgb(34, 34, 34);"=
><br></span></span></p><p class=3D"MsoNoSpacing"><span style=3D"color: rgb(=
0, 112, 192);">Please explain how the list is created and advise how
ABIs should deal with this in case of shared libraries and that of static
libraries. Assume you can&#39;t modify the linker.</span><br></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Good
hint. I have modified it in the document. Thanks. The static class construc=
tor,
is now behaving exactly the same as a default class constructor of global
variable, except have no associated object. Therefore the same mechanism ca=
n be
used to execute it with NULL instead of object pointer. This does not requi=
res
to modify linker.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">You declare static constructors as if they had a return type of the
class type: static MyClass() { ... };, which I think is inconsistent with
current C++ grammar. Note that in the position where you&#39;ve put MyClass=
, we
usually put (loosely speaking) return type. This includes the (non-static)
constructor(s), which evaluate to MyClass and have no name. Possible fixes =
for
this include static void() { ... }; and static void MyClass() { ... };, the
second being a clash on a typical error that is usually reported separately=
 by
the compiler. Or you might use a single name for all types, e.g. static voi=
d
constructor() { ... };.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">I see
your point, but you cannot declare function with no name, so if the functio=
n
returns MyClass it will be: [static] MyClass identifier(=E2=80=A6); but in =
case of
default/static class constructor, you have no such problem, because MyClass=
 is
always followed by parenthesis and constructors have no returned type. Then=
 we
have no ambiguity here. Did I properly understood your comment?<o:p></o:p><=
/span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">However, if your constructor really returns void, how will you handl=
e
errors? Normally constructors are either exception-safe (read: we ignore so=
me
exceptions that we want to fail early for) or report error by throwing
something. Having a static int constructor_error_code doesn&#39;t really he=
lp if
the constructor doesn&#39;t execute fully.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">I am not
sure about this. Your static int variable if declared in global scope will =
be
initialized before static class constructor is executed. You can then use i=
t to
mark failure initially and set it to successful just before returning from
constructors code. The exceptions are working as in case of default class
constructor for global variables, so will have similar problems here.<o:p><=
/o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">Your document requires linker support. That goes way beyond C++: eve=
n if
we standardized static constructors, if you require linkers to be changed, =
then
it&#39;s perhaps the best to first ask linkers to allow for this. This is a
dependency for compiler implementers.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">I
modified the document to avoid linker modification. The static class
constructors uses now the same execution mechanism as for constructors of
global object.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">What about DLL / .so files? It&#39;s already kind of a nightmare to =
have
static initialization there. These would need very clear recipes to have th=
em
defect free.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">It would
be very nice to have such functionality finally working in C++. Nevertheles=
s as
linker cannot be modified, I am not addressing it anymore in the document. =
I=E2=80=99ll
try to issue another document to cover this problem regarding both static c=
lass
constructor and global variable initialization.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">Correct me if I&#39;m wrong, it&#39;ll need at least a static bool p=
er class to
know it it&#39;s been initialized as two libs might have the same class. In=
 that
case, it&#39;s just a syntax sugar over static bool constructor_result =3D =
[]{ ...
}()<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Could
you please explain it a little bit more? When you would like to use this st=
atic
bool with lambda? I do know it is used to execute code once, but how is thi=
s
related? The lambda will not be called if object is not created unlike the
static class constructor.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">Having a static bool (non-const) for each template class I instantia=
te
would make me invest in memory modules.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">I do not
think this static bool is anywhere needed as it can be determined once on p=
rogram
linking stage.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">I suggest underlining (and explaining why is) that, unlike default
constructors, they&#39;re not auto-generated if missing.<o:p></o:p></span><=
/p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Good
hint, I=E2=80=99ll cover it. Thanks. Actually we cannot say they are auto-g=
enerated if
missing. The static class constructor can initialize static class members
through initializer list as non-static members are initialized through clas=
s
constructor. However, if you have no default constructor, members are
initialized with its default constructor. We cannot achieve this static cla=
ss
constructor, just to be backward compatible. If you have no static class co=
nstructor,
you must define the static member outside the class body as usual. When sta=
tic
class constructor is defined, all static members not defined on initializer
list will be initialized with its default constructor, even if they are not
defined outside the class body. So the backward compatibility is the reason=
..<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">Which brings us to... can&#39;t these be unified? As a workaround fo=
r some
static init issues, we used to have something like (feel free to laugh): [=
=E2=80=A6] Terrible
as it seems, it actually fixes all the ordering issues re: dependencies,
inheritance, multi-init; it can be run from main() or DllMain() by a simple
DEPS();, in which case it runs after static initializer. You might take thi=
s
and modify to your needs when you want to specify the as-if of static ctor
implementation. You might want to expose ready (or drop it if you wish) and
make tha call to DEPS(); in main()-like functions automatic.<o:p></o:p></sp=
an></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Interesting.
Assuming void deps() is also static. In your code you have a chain of
execution, but each class depend (indirectly) on the other. Moreover DEPS i=
s in
a single translation unit only. Additionally, the more calls you have, the =
more
stack you use. IMHO it is better/safer to build a list (array) of pointers =
to
functions and then execute it one by one. However definitely the best way q=
ould
be tu use the static class constructor, which provides more OOP way to do t=
his.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">You&#39;re okay to allocate one byte per class for static destructor=
s, but
didn&#39;t seem okay to allocate one bit per class for static constructor? =
Why is
that? Or is there something I&#39;m missing?<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Where I
stated that? No additional allocations are needed. In the above example wit=
h
MyPlugin, static object was used to simplify the example. However, of cours=
e depending
on compiler configuration, empty class can have a zero-length.<o:p></o:p></=
span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">do you want static constructors to be (manually) callable?<o:p></o:p=
></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">No, this
feature is not available. It was already covered in document.<o:p></o:p></s=
pan></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">do you want to be able to take their address?<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">No,
there is no way to do this.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">does it make sense to have static constructors with parameters (and =
if
yes, who would fill them: OS passing argc, argv[] or base / descendant, any=
one
else?)<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">No, you
cannot pass parameters to the static class constructor. It was already cove=
red
in document.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">is there a way to inherit static ctors? (e.g. AbstractPlugin comes t=
o
mind) If yes, how do we get current (most derived) type?<o:p></o:p></span><=
/p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Yes. Thank
you for pointing that as I forgotten to cover it in the document. Static cl=
ass
constructors are executed/inherited in the same manner as default construct=
ors.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">do you need static construction to be sequential, or just
base-before-descendant? allowing for, but not requiring parallel initializa=
tion
might speed up start-up without putting a burden on compilers.<o:p></o:p></=
span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Sequential
approach seems to be the most appropriate and as above mentioned, the stati=
c
class constructor of base class will be executed first, then are initialize=
d
static members defined (and not defined) =C2=A0through the initializer list=
.. Finally the code
of static class constructor is executed.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">can you instantiate _other_ classes during static construction? it&#=
39;s
possible that their static ctor is not yet run, or that you have an
inter-dependency.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">You can
instantiate classes and their static class constructors will be executed
before, same as global variables are initialized. The initialization is per=
formed
in definition order within single translation unit. Compare its behavior to
class constructor execution of global variables.<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">are vtables constructed by the time constructors are run?<o:p></o:p>=
</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">vtables
are generated before; as for class constructor of global variables.<o:p></o=
:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">can you initialize static (const) reference members and what&#39;s t=
he
syntax?<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">Hm,
actually why not through initializers list? Any objection?<o:p></o:p></span=
></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">=C2=A0</span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US" style=3D"color:#0070C0;mso-a=
nsi-language:
EN-US">can you throw an object that&#39;s class is being statically constru=
cted?<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><span lang=3D"EN-US">I am
thinking about this use case, but I do not see your point. Can you elaborat=
e a
little bit more please?<o:p></o:p></span></p>

<p class=3D"MsoNoSpacing"><br></p><p class=3D"MsoNoSpacing">Best Regards,</=
p><p class=3D"MsoNoSpacing">Mariusz</p></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ef622675-478b-4cf3-a9a6-d28433553f27%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ef622675-478b-4cf3-a9a6-d28433553f27=
%40isocpp.org</a>.<br />

------=_Part_2696_780331532.1472318094908--

------=_Part_2695_385220036.1472318094907
Content-Type: text/html; charset=ISO-8859-1;
 name="static class constructor.htm"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="static class constructor.htm"
X-Attachment-Id: 292d31a7-f419-434b-b330-5a181c6ba8ec
Content-ID: <292d31a7-f419-434b-b330-5a181c6ba8ec>

<p>Document Number: D0421R1<br />
Audience: Evolution Working Group (EWG)<br />
Mariusz Moczala &lt;<a href=3D"mailto:mmoczala@gmail.com">mmoczala@gmail.co=
m</a>&gt;<br />
Date: 2016-07-24</p>

<h1>Static class constructor</h1>

<h2 id=3D"content">1. Content</h2>
<p><a href=3D"#content">1. Content</a><br />
<a href=3D"#abstract">2. Abstract</a><br />
<a href=3D"#motivation">3. Motivation</a><br />
<a href=3D"#impact_on_the_standard">4. Impact On the Standard</a><br />
<a href=3D"#design_decisions">5. Design Decisions</a><br />
<a href=3D"#declaration_and_definition">5.1. Declaration and definition</a>=
<br />
<a href=3D"#parameters">5.2. Parameters</a><br />
<a href=3D"#this_pointer">5.3. This pointer</a><br />
<a href=3D"#execution_order">5.4. Execution order</a><br />
<a href=3D"#inheritance">5.5. Inheritance</a><br />
<a href=3D"#initializer_list">5.6. Initializer list</a><br />
<a href=3D"#one_definition_rule">5.7. One Definition Rule</a><br />
<a href=3D"#auto_generation">5.8. Auto generation</a><br />
<a href=3D"#local_classes">5.9. Local classes</a><br />
<a href=3D"#static_destructor">5.10. Static destructor</a><br />
<a href=3D"#static_inline_variables">6. Static inline variables</a><br />
<a href=3D"#references">7. References</a></p>

<h2 id=3D"abstract">2. Abstract</h2>
<p>As a class constructor is dedicated for object initialization, proposed =
static class constructor offers type registration. When class defines stati=
c class constructor, it code is executed once, early before <i>main()</i> f=
unction execution. As usual static member function, static class constructo=
r have no associated object and has access to all the static members of the=
 class.</p>

<h2 id=3D"motivation">3. Motivation</h2>
<p>Static class constructor allows execution of class code, without calling=
 it from outside the class body. This feature provides flexible and object =
oriented way to register new functionality of an application. Currently it =
can be achieved through creation of dummy global variable, where default cl=
ass constructor of that variable performs additional code for such registra=
tion. Nevertheless, without static class constructor, this cannot be achiev=
ed in header-only code. Please refer to <a href=3D"#design_decisions">Desig=
n Decisions</a> for example usage. The static class constructors offers:</p=
>

<p><ul>
<li>consistent and object oriented mechanism for type registration</li>
<li>static member initialization through initializer list of static class c=
onstructor</li>
<li>execution of class code without calling it directly from outside the cl=
ass body</li>
</ul></p>

<h2 id=3D"impact_on_the_standard">4. Impact On the Standard</h2>
<p>This proposal adds new language feature which affects a compiler only.</=
p>
<p>The feature is backward compatible as classes does not has to provide a =
definition of static class constructor. When class defines a static class c=
onstructor, used syntax is identical with declaration and definition of def=
ault class constructor, except that the static class constructor name is pr=
eceded by <i>static</i> keyword.</p>
<p>Static class constructor is executed once for each class defining such c=
onstructor. It happens exactly in the same manner as for constructors of ob=
jects defined at global scope. Both are always executed before execution of=
 <i>main()</i> function. Program startup code uses the same mechanism to ex=
ecute both, constructors of global variables, and static class constructors=
.. For static class constructors pointer to associated object can be undefin=
ed or set to <i>NULL</i>, as <i>this</i> keyword is not available for stati=
c class constructors.</p>
<p>Static class variables can be initialized on member initializer list of =
static class constructor. Therefore, when single header is used for multipl=
e translation units, One Definition Rule must be meet.</p>

<h2 id=3D"design_decisions">5. Design Decisions</h2>
<p>For better clarification, please consider the following code using a sta=
tic class constructor:</p>
<pre>class MyPlugin : public Plugin {
  public:
    static MyPlugin() {
      static MyPlugin myPlugin;
      Plugins::registerPlugin(&amp;myPlugin);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
};</pre>
<p>Which is equivalent to the following, when defined at global scope:</p>
<pre>class MyPlugin : public Plugin {
  public:
    MyPlugin() {
      Plugins::registerPlugin(this);
    }
    ~MyPlugin() {
      Plugins::unregisterPlugin(this);
    }
} myPlugin;</pre>
<p>The equivalent code have some pitfalls which can be avoided with static =
class constructor:</p>
<p><ul>
<li>There is no need to create dummy global variable to perform initializat=
ion.</li>
<li>Each dummy global variable used in initialization have associated ident=
ifier and therefore is visible under IntelliSense. It becomes more difficul=
t in navigation for projects using multiple dummy global variables.</li>
<li>Static constructors allows to perform early initialization for headers-=
only libraries, where global variables cannot easily be used.</li>
</ul></p>

<h3 id=3D"declaration_and_definition">5.1. Declaration and definition</h3>
<p>Class does not have to provide a declaration nor definition of static cl=
ass constructor. When class defines a static class constructor, used syntax=
 is identical with declaration and definition of default class constructor,=
 except that the static class constructor name is preceded by static keywor=
d.</p>

<h3 id=3D"parameters">5.2. Parameters</h3>
<p>The static class constructor is called once by program startup code. It =
cannot be executed manually and its address cannot be obtained. It does not=
 take any arguments as in case of default class constructor.</p>

<h3 id=3D"this_pointer">5.3. This pointer</h3>
<p>The static class constructor is not associated with an object as other s=
tatic class functions. Therefore <i>this</i> pointer is not available for s=
tatic class constructors.</p>

<h3 id=3D"execution_order">5.4. Execution order</h3>
<p>Static class constructors are executed one by one among execution of cla=
ss constructors for variables defined at global scope in order of consecuti=
ve definitions occurring in translation unit.</p>

<h3 id=3D"inheritance">5.5. Inheritance</h3>
<p>Static class constructors are inherited exactly in the same manner as in=
 case of default class constructors. Consecutive actions are taken in follo=
wing order:</p>
<p><ul>
<li>execution of static class constructors of base classes in order form th=
e top most class,</li>
<li>initialization of static members not defined through the initializer li=
st,</li>
<li>initialization of static members defined through the initializer list,<=
/li>
<li>execution of static class constructor code.</li>
</ul></p>

<h3 id=3D"initializer_list">5.6. Initializer list</h3>
<p>The static class constructor is a good place to provide initialization o=
f static class members. It can be achieved through initializer list as for =
non-static class member initialization on non-static class constructor init=
ializer list.</p>

<h3 id=3D"one_definition_rule">5.7. One Definition Rule</h3>
<p>When single header is used for multiple translation units, One Definitio=
n Rule must be meet to avoid static member redefinition.</p>

<h3 id=3D"auto_generation">5.8. Auto generation</h3>
<p>The static class constructor can initialize static class members through=
 initializer list as non-static members are initialized through class const=
ructor. However in case when default class constructor is not defined for c=
lass, object members are initialized with its default constructors. This ca=
nnot be achieved for static class constructor, to be backward compatible. T=
herefore, if static class constructor is not defined, static class member v=
ariable must be defined outside the class body as usual. Otherwise, when st=
atic class constructor is defined, all static members not defined through i=
nitializer list will be initialized with its default constructors, even if =
they are not defined outside the class body.</p>

<h3 id=3D"local_classes">5.9. Local classes</h3>
<p>There is no distinction between static class constructors defined for cl=
asses at global and local scope.</p>

<h3 id=3D"static_destructor">5.10. Static class destructor</h3>
<p>A static class destructor was also considered on early proposal stage. I=
t could however work in similar way to static class constructor, but to per=
form type deregistration. It has been found that introducing such functiona=
lity can be simply replaced with classical destructor, as static class cons=
tructor allow to create a static object, which will be destroyed on process=
 termination.</p>
<p>Nevertheless it would be very useful to have a static class destructor a=
long with static class constructor, as it may open new possibilities which =
were not so obviously visible at the time when this document was created.</=
p>

<h3 id=3D"static_inline_variables">6. Static inline variables</h3>
<p>The static class constructor offers similar features to static inline va=
riables proposed for C++17 standard. However both proposals are not excludi=
ng each other. As static inline variables are dedicated for static class me=
mber initialization, achieving early initialization functionality through s=
tatic inline variables is more difficult and have more complicated syntax. =
In this case static class constructor is more reasonable.</p>

<h3 id=3D"references">7. References</h3>
<p><ul>
<li>ISO C++ Standard (ISO/IEC 14882) 2003, section 3.2.</li>
<li>Hal Finkel and Richard Smith, Inline Variables, 2015=AD04=AD07, N4424, =
<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pd=
f">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf</a></l=
i>
</ul></p>

------=_Part_2695_385220036.1472318094907--

.


Author: k.saurabh2k10@gmail.com
Date: Wed, 18 Apr 2018 07:55:55 -0700 (PDT)
Raw View
------=_Part_33332_2126337729.1524063355651
Content-Type: multipart/alternative;
 boundary="----=_Part_33333_418467215.1524063355652"

------=_Part_33333_418467215.1524063355652
Content-Type: text/plain; charset="UTF-8"

Same code if I run I get :

main.cpp:57:20: error: constructor cannot be static member function
         static Log()


On Tuesday, 26 July 2016 20:20:34 UTC+5:30, Mariusz Moczala wrote:
>
> Hello once again,
>
> Please tell me what do you think about the following example:
>
> #include <cstdio>
> #include <string>
>
> class LogFile
> {
>     private:
>
>         FILE *file;
>
>
>     public:
>
>         LogFile() :
>             file(NULL)
>         {
>         }
>
>         ~LogFile()
>         {
>             close();
>         }
>
>         void append(const char *fileName)
>         {
>             close();
>             file = fopen(fileName, "a+t");
>         }
>
>         void close()
>         {
>             if(file) {
>                 fclose(file);
>                 file = NULL;
>             }
>         }
>
>         bool isOpened() const
>         {
>             return file != NULL;
>         }
>
>         void write(const char *message)
>         {
>             fprintf(file, "%s\n", message);
>         }
> };
>
> class Log
> {
>     private:
>
>         static LogFile logFile;
>
>
>     public:
>
>         static Log()
>         {
>             logFile.append("log.txt");
>             if(!logFile.isOpened())
>                 fprintf(stderr, "ERROR: Failed to create 'log.txt'
> file.\n");
>         }
>
>
>     private:
>
>         std::string str;
>
>
>     public:
>
>         ~Log()
>         {
>             logFile.write(str.c_str());
>         }
>
>         void write(const char *text)
>         {
>             if(str.length())
>                 str += "    ";
>             str += text;
>             str += '\n';
>         }
> };
>
> int main()
> {
>     Log logAlpha, logNum;
>     logAlpha.write("A message");
>     logNum.write("1 message");
>     logAlpha.write("B message");
>     logNum.write("2 message");
>     logAlpha.write("C message");
>     logNum.write("3 message");
>
>     return 0;
> }
>
> OUTPUT:
>
> 1 message
>     2 message
>     3 message
>
> A message
>     B message
>     C message
>
> Regarding the code marked in blue:
>
>    - The static logFile variable is defined because a static class
>    constructor is defined. The static variable can be also initialized through
>    initializer list
>    - The static class constructor is executed once, so you can perform
>    actions like filie open
>    - The static logFile variable will be destroyed on application
>    termination as usual static variable
>    - Is this a kind of a singleton or not?
>
>
> Many thanks,
> Mariusz
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/51fd88eb-b0d2-4f35-b069-2eb2bb283f2a%40isocpp.org.

------=_Part_33333_418467215.1524063355652
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Same code if I run I get :<div><br></div><div><pre class=
=3D"msg" style=3D"box-sizing: border-box; overflow: auto; font-family: Menl=
o, Monaco, Consolas, &quot;Courier New&quot;, monospace; padding: 9.5px; li=
ne-height: 1.42857; color: white; word-break: break-all; word-wrap: break-w=
ord; background-color: rgb(51, 51, 51); border-width: 1px; border-style: so=
lid; border-color: rgb(204, 204, 204); border-radius: 4px;"><span style=3D"=
box-sizing: border-box; color: rgb(255, 91, 74);"><span class=3D"error_line=
" style=3D"box-sizing: border-box; cursor: pointer; text-decoration-line: u=
nderline;">main.cpp:57:20</span>: error: constructor cannot be static membe=
r function</span>
         static Log()</pre><div><br></div>On Tuesday, 26 July 2016 20:20:34=
 UTC+5:30, Mariusz Moczala  wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>Hello once again,</div><div><br></div><div>Plea=
se tell me what do you think about the following example:</div><div><br></d=
iv><div><font face=3D"courier new, monospace">#include &lt;cstdio&gt;</font=
></div><div><font face=3D"courier new, monospace">#include &lt;string&gt;</=
font></div><div><font face=3D"courier new, monospace"><br></font></div><div=
><font face=3D"courier new, monospace">class LogFile</font></div><div><font=
 face=3D"courier new, monospace">{</font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 private:</font></div><div><font face=3D"courie=
r new, monospace"><br></font></div><div><font face=3D"courier new, monospac=
e">=C2=A0 =C2=A0 =C2=A0 =C2=A0 FILE *file;</font></div><div><font face=3D"c=
ourier new, monospace"><br></font></div><div><font face=3D"courier new, mon=
ospace"><br></font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 public:</font></div><div><font face=3D"courier new, monospace"><br><=
/font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 LogFile() :</font></div><div><font face=3D"courier new, monospace">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file(NULL)</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div>=
<div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</f=
ont></div><div><font face=3D"courier new, monospace"><br></font></div><div>=
<font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~LogFile(=
)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><fon=
t face=3D"courier new, monospace"><br></font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void append(const char *file=
Name)</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 close();</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =
=3D fopen(fileName, &quot;a+t&quot;);</font></div><div><font face=3D"courie=
r new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=
=3D"courier new, monospace"><br></font></div><div><font face=3D"courier new=
, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void close()</font></div><div><fon=
t face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div=
><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 if(file) {</font></div><div><font face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(file);</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file =3D NULL;</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br></font>=
</div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 bool isOpened() const</font></div><div><font face=3D"courier new, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font face=3D"courier =
new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return file !=3D =
NULL;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace"><br>=
</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 void write(const char *message)</font></div><div><font face=3D"c=
ourier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
fprintf(file, &quot;%s\n&quot;, message);</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font =
face=3D"courier new, monospace">};</font></div><div><font face=3D"courier n=
ew, monospace"><br></font></div><div><font face=3D"courier new, monospace">=
class Log</font></div><div><font face=3D"courier new, monospace">{</font></=
div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 private:</font></div><div><font face=3D"courier new, monospace" color=
=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static LogFile logFile;</font><=
/div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></fon=
t></div><div><font face=3D"courier new, monospace" color=3D"#0000ff"><br></=
font></div><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=
=A0 =C2=A0 public:</font></div><div><font face=3D"courier new, monospace" c=
olor=3D"#0000ff"><br></font></div><div><font face=3D"courier new, monospace=
" color=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static Log()</font></div><d=
iv><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 {</font></div><div><font face=3D"courier new, monospace" colo=
r=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logFile.append(&quo=
t;log.txt&quot;);</font></div><div><font face=3D"courier new, monospace" co=
lor=3D"#0000ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if(!logFile.isOpe=
ned())</font></div><div><font face=3D"courier new, monospace" color=3D"#000=
0ff">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr=
, &quot;ERROR: Failed to create &#39;log.txt&#39; file.\n&quot;);</font></d=
iv><div><font face=3D"courier new, monospace" color=3D"#0000ff">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D"courier new, monospace">=
<br></font></div><div><font face=3D"courier new, monospace"><br></font></di=
v><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 private:</font><=
/div><div><font face=3D"courier new, monospace"><br></font></div><div><font=
 face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::string st=
r;</font></div><div><font face=3D"courier new, monospace"><br></font></div>=
<div><font face=3D"courier new, monospace"><br></font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 public:</font></div><div><font fa=
ce=3D"courier new, monospace"><br></font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ~Log()</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</font></div><di=
v><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 logFile.write(str.c_str());</font></div><div><font face=3D"courier n=
ew, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><font face=3D"courier new, m=
onospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void write(const char *text)</font></=
div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
{</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 if(str.length())</font></div><div><font face=3D"co=
urier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 str +=3D &quot; =C2=A0 =C2=A0&quot;;</font></div><div><font face=3D"cou=
rier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D tex=
t;</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 str +=3D &#39;\n&#39;;</font></div><div><font face=
=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div>=
<font face=3D"courier new, monospace">};</font></div><div><font face=3D"cou=
rier new, monospace"><br></font></div><div><font face=3D"courier new, monos=
pace">int main()</font></div><div><font face=3D"courier new, monospace">{</=
font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 Log log=
Alpha, logNum;</font></div><div><font face=3D"courier new, monospace">=C2=
=A0 =C2=A0 logAlpha.write(&quot;A message&quot;);</font></div><div><font fa=
ce=3D"courier new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;1 message&qu=
ot;);</font></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 =
logAlpha.write(&quot;B message&quot;);</font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 logNum.write(&quot;2 message&quot;);</font=
></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 logAlpha.wr=
ite(&quot;C message&quot;);</font></div><div><font face=3D"courier new, mon=
ospace">=C2=A0 =C2=A0 logNum.write(&quot;3 message&quot;);</font></div><div=
><font face=3D"courier new, monospace"><br></font></div><div><font face=3D"=
courier new, monospace">=C2=A0 =C2=A0 return 0;</font></div><div><font face=
=3D"courier new, monospace">}</font></div><div><br></div><div>OUTPUT:</div>=
<div><br></div><div><font face=3D"courier new, monospace">1 message</font><=
/div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 2 message</fo=
nt></div><div><font face=3D"courier new, monospace">=C2=A0 =C2=A0 3 message=
</font></div><div><font face=3D"courier new, monospace"><br></font></div><d=
iv><font face=3D"courier new, monospace">A message</font></div><div><font f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0 B message</font></div><div><fo=
nt face=3D"courier new, monospace">=C2=A0 =C2=A0 C message</font></div><div=
><br></div><div>Regarding the code marked in <font color=3D"#0000ff">blue</=
font>:</div><div><ul><li>The static logFile variable is defined because a s=
tatic class constructor is defined. The static variable can be also initial=
ized through initializer list<br></li><li>The static class constructor is e=
xecuted once, so you can perform actions like filie open<br></li><li>The st=
atic logFile variable will be destroyed on application termination as usual=
 static variable<br></li><li>Is this a kind of a singleton or not?<br></li>=
</ul></div><div><br></div><div>Many thanks,</div><div>Mariusz</div></div></=
blockquote></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/51fd88eb-b0d2-4f35-b069-2eb2bb283f2a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/51fd88eb-b0d2-4f35-b069-2eb2bb283f2a=
%40isocpp.org</a>.<br />

------=_Part_33333_418467215.1524063355652--

------=_Part_33332_2126337729.1524063355651--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Wed, 18 Apr 2018 15:11:45 +0000
Raw View
--000000000000317b0f056a20e018
Content-Type: text/plain; charset="UTF-8"

This group is for proposals that change the standard to add new capability.
You won't find many posts here with code that actually works yet, just code
that people want to work in the future.

On Wed, 18 Apr 2018, 15:55 , <k.saurabh2k10@gmail.com> wrote:

> Same code if I run I get :
>
> main.cpp:57:20: error: constructor cannot be static member function
>          static Log()
>
>
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPMnaCVexVyvacTi8rp_NDjeBpAJiMBXRSJ%2B%3DYJ8HVDnA%40mail.gmail.com.

--000000000000317b0f056a20e018
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto">This group is for proposals that change the standard to a=
dd new capability. You won&#39;t find many posts here with code that actual=
ly works yet, just code that people want to work in the future.<br><br><div=
 class=3D"gmail_quote" dir=3D"auto"><div dir=3D"ltr">On Wed, 18 Apr 2018, 1=
5:55 , &lt;<a href=3D"mailto:k.saurabh2k10@gmail.com">k.saurabh2k10@gmail.c=
om</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
Same code if I run I get :<div><br></div><div><pre class=3D"m_-207126384060=
7435715msg" style=3D"box-sizing:border-box;overflow:auto;font-family:Menlo,=
Monaco,Consolas,&quot;Courier New&quot;,monospace;padding:9.5px;line-height=
:1.42857;color:white;word-break:break-all;word-wrap:break-word;background-c=
olor:rgb(51,51,51);border-width:1px;border-style:solid;border-color:rgb(204=
,204,204);border-radius:4px"><span style=3D"box-sizing:border-box;color:rgb=
(255,91,74)"><span class=3D"m_-2071263840607435715error_line" style=3D"box-=
sizing:border-box;text-decoration-line:underline">main.cpp:57:20</span>: er=
ror: constructor cannot be static member function</span>
         static Log()</pre></div></div><br>
</blockquote></div></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPMnaCVexVyvacTi8rp_NDjeBpAJi=
MBXRSJ%2B%3DYJ8HVDnA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPM=
naCVexVyvacTi8rp_NDjeBpAJiMBXRSJ%2B%3DYJ8HVDnA%40mail.gmail.com</a>.<br />

--000000000000317b0f056a20e018--

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Wed, 18 Apr 2018 09:55:26 -0700 (PDT)
Raw View
------=_Part_33392_2125649304.1524070526650
Content-Type: multipart/alternative;
 boundary="----=_Part_33393_475200827.1524070526650"

------=_Part_33393_475200827.1524070526650
Content-Type: text/plain; charset="UTF-8"

That's right. This is the proposal to C++ standard.
Nevertheless I am very happy that it is the feature which people need.
I see many modern languages having this static class constructors already.


On Wednesday, April 18, 2018 at 5:11:59 PM UTC+2, Jake Arkinstall wrote:
>
> This group is for proposals that change the standard to add new
> capability. You won't find many posts here with code that actually works
> yet, just code that people want to work in the future.
>
> On Wed, 18 Apr 2018, 15:55 , <k.saur...@gmail.com <javascript:>> wrote:
>
>> Same code if I run I get :
>>
>> main.cpp:57:20: error: constructor cannot be static member function
>>          static Log()
>>
>>
>>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/240aebb5-f544-40d1-842f-8fb5eeb3ab52%40isocpp.org.

------=_Part_33393_475200827.1524070526650
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">That&#39;s right. This is the proposal to C++ standard.<di=
v>Nevertheless I am very happy that it is the feature which people need.<di=
v>I see many modern languages having this static class constructors already=
..=C2=A0</div></div><div><br></div><br>On Wednesday, April 18, 2018 at 5:11:=
59 PM UTC+2, Jake Arkinstall wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"auto">This group is for proposals that change the standar=
d to add new capability. You won&#39;t find many posts here with code that =
actually works yet, just code that people want to work in the future.<br><b=
r><div class=3D"gmail_quote" dir=3D"auto"><div dir=3D"ltr">On Wed, 18 Apr 2=
018, 15:55 , &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"Zp6uVF8rCgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;">k.saur...@gmail.com</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">Same code if I run I get :<div><br></div><di=
v><pre style=3D"overflow:auto;font-family:Menlo,Monaco,Consolas,&quot;Couri=
er New&quot;,monospace;padding:9.5px;line-height:1.42857;color:white;word-b=
reak:break-all;word-wrap:break-word;background-color:rgb(51,51,51);border-w=
idth:1px;border-style:solid;border-color:rgb(204,204,204);border-radius:4px=
"><span style=3D"color:rgb(255,91,74)"><span>main.cpp:57:20</span>: error: =
constructor cannot be static member function</span>
         static Log()</pre></div></div><br>
</blockquote></div></div>
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/240aebb5-f544-40d1-842f-8fb5eeb3ab52%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/240aebb5-f544-40d1-842f-8fb5eeb3ab52=
%40isocpp.org</a>.<br />

------=_Part_33393_475200827.1524070526650--

------=_Part_33392_2125649304.1524070526650--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 19 Apr 2018 01:05:51 -0700
Raw View
On Wednesday, 18 April 2018 09:55:26 PDT Mariusz Moczala wrote:
> That's right. This is the proposal to C++ standard.
> Nevertheless I am very happy that it is the feature which people need.
> I see many modern languages having this static class constructors already.

Then please explain what a static class constructor is and does, who needs it,
and how it improves developers' lives.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/117295243.JcN584e9Rb%40tjmaciei-mobl1.

.


Author: Mariusz Moczala <mmoczala@gmail.com>
Date: Thu, 19 Apr 2018 03:37:46 -0700 (PDT)
Raw View
------=_Part_2311_1668026465.1524134266146
Content-Type: multipart/alternative;
 boundary="----=_Part_2312_908353864.1524134266146"

------=_Part_2312_908353864.1524134266146
Content-Type: text/plain; charset="UTF-8"

Sure, with pleasure! lets call them SCC (Static Class Constructor) and SCD
(Static Class Destructor)
for simplification.


WHAT IS IT?

SCC and SCD are special kind of constructor/destructor which is associathed
with class (type) rather
than with the object. What is certain from developers point of view is that
SCC is called only once
before entering the scope where corresponding type (class) is defined and
SCD once after leaving it.
When type is defined in global scope SCC is called once before execution of
main() function and SCD
once after.


WHO NEED IT?

Definitely those who write modern and header only libraries in C++. Every
year more and more libraries
are created as header only code. In such code to initialize some content
developers can for example
create a dedicated singleton class with special mechanisms for
initialization, unfortunately user of
the library have to manually execute this initialization. Developers of the
library can also provide
a lazy initialization, however not in every case it can be used. Using an
object declared as a global
variable is a nightmare in this case. It have to be initialized in only one
translation unit, so where
to put it? Definitely not in the header file as including it in many
translation units will lead to
fail linking. And moreover, where to put initialization of static class
members in header only code?


HOW IT IMPROVES DEVELOPERS LIVES?

And here comes elegant, single line solution with SCC and/or SCD.
Declared/Defined as classic class
constructor but preceded with static keyword. It takes no arguments. As
classical static function it
is not associated with any object, so the this keyword is not available
here. Initialization of
static members can be done through initializers list of SCC. It is excelent
place to execute early
initialization code. Through One Definition Rule (ODR is already in C++
standard) it solves all
complication related to linking.


I encourage you to read more in old proposal available here:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0421r0.html


On Thursday, April 19, 2018 at 10:05:54 AM UTC+2, Thiago Macieira wrote:
>
> On Wednesday, 18 April 2018 09:55:26 PDT Mariusz Moczala wrote:
> > That's right. This is the proposal to C++ standard.
> > Nevertheless I am very happy that it is the feature which people need.
> > I see many modern languages having this static class constructors
> already.
>
> Then please explain what a static class constructor is and does, who needs
> it,
> and how it improves developers' lives.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5cb53bf0-5f06-4f4c-bf45-2ab7c1bd0890%40isocpp.org.

------=_Part_2312_908353864.1524134266146
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Sure, with pleasure! lets call them SCC (Static Class=
 Constructor) and SCD (Static Class Destructor)</div><div>for simplificatio=
n.</div><div><br></div><div><br></div><div>WHAT IS IT?</div><div><br></div>=
<div>SCC and SCD are special kind of constructor/destructor which is associ=
athed with class (type) rather</div><div>than with the object. What is cert=
ain from developers point of view is that SCC is called only once</div><div=
>before entering the scope where corresponding type (class) is defined and =
SCD once after leaving it.</div><div>When type is defined in global scope S=
CC is called once before execution of main() function and SCD</div><div>onc=
e after.</div><div><br></div><div><br></div><div>WHO NEED IT?</div><div><br=
></div><div>Definitely those who write modern and header only libraries in =
C++. Every year more and more libraries</div><div>are created as header onl=
y code. In such code to initialize some content developers can for example<=
/div><div>create a dedicated singleton class with special mechanisms for in=
itialization, unfortunately user of</div><div>the library have to manually =
execute this initialization. Developers of the library can also provide</di=
v><div>a lazy initialization, however not in every case it can be used. Usi=
ng an object declared as a global</div><div>variable is a nightmare in this=
 case. It have to be initialized in only one translation unit, so where</di=
v><div>to put it? Definitely not in the header file as including it in many=
 translation units will lead to</div><div>fail linking. And moreover, where=
 to put initialization of static class members in header only code?</div><d=
iv><br></div><div><br></div><div>HOW IT IMPROVES DEVELOPERS LIVES?</div><di=
v><br></div><div>And here comes elegant, single line solution with SCC and/=
or SCD. Declared/Defined as classic class</div><div>constructor but precede=
d with static keyword. It takes no arguments. As classical static function =
it</div><div>is not associated with any object, so the this keyword is not =
available here. Initialization of</div><div>static members can be done thro=
ugh initializers list of SCC. It is excelent place to execute early</div><d=
iv>initialization code. Through One Definition Rule (ODR is already in C++ =
standard) it solves all</div><div>complication related to linking.</div><di=
v><br></div><div><br></div><div>I encourage you to read more in old proposa=
l available here:</div><div>http://open-std.org/JTC1/SC22/WG21/docs/papers/=
2016/p0421r0.html<br></div><div><br></div><br>On Thursday, April 19, 2018 a=
t 10:05:54 AM UTC+2, Thiago Macieira wrote:<blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">On Wednesday, 18 April 2018 09:55:26 PDT Mariusz Moczala wrote=
:
<br>&gt; That&#39;s right. This is the proposal to C++ standard.
<br>&gt; Nevertheless I am very happy that it is the feature which people n=
eed.
<br>&gt; I see many modern languages having this static class constructors =
already.
<br>
<br>Then please explain what a static class constructor is and does, who ne=
eds it,=20
<br>and how it improves developers&#39; lives.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br>
<br>
<br></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5cb53bf0-5f06-4f4c-bf45-2ab7c1bd0890%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5cb53bf0-5f06-4f4c-bf45-2ab7c1bd0890=
%40isocpp.org</a>.<br />

------=_Part_2312_908353864.1524134266146--

------=_Part_2311_1668026465.1524134266146--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Thu, 19 Apr 2018 15:54:00 +0300
Raw View
On 04/19/18 13:37, Mariusz Moczala wrote:
> Sure, with pleasure! lets call them SCC (Static Class Constructor) and
> SCD (Static Class Destructor)
> for simplification.
>
>
> WHAT IS IT?
>
> SCC and SCD are special kind of constructor/destructor which is
> associathed with class (type) rather
> than with the object. What is certain from developers point of view is
> that SCC is called only once
> before entering the scope where corresponding type (class) is defined
> and SCD once after leaving it.
> When type is defined in global scope SCC is called once before execution
> of main() function and SCD
> once after.

Since the constructor/destructor in this case does not
construct/destruct an object in this model, I don't see why it should be
a constructor/destructor in the first place. The whole involvement of a
type to define SCC/SCD looks like a kludge to me.

If you want a function called on program startup or termination, you'd
better look at standardizing
__attribute__((constructor))/__attribute__((destructor))[1]. You'd have
to present a rationale for why a global variable with a
constructor/destructor doesn't cut it and in the latter case - why
std::atexit doesn't cut it.

[1]:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

> WHO NEED IT?
>
> Definitely those who write modern and header only libraries in C++.
> Every year more and more libraries
> are created as header only code. In such code to initialize some content
> developers can for example
> create a dedicated singleton class with special mechanisms for
> initialization, unfortunately user of
> the library have to manually execute this initialization. Developers of
> the library can also provide
> a lazy initialization, however not in every case it can be used. Using
> an object declared as a global
> variable is a nightmare in this case. It have to be initialized in only
> one translation unit, so where
> to put it? Definitely not in the header file as including it in many
> translation units will lead to
> fail linking. And moreover, where to put initialization of static class
> members in header only code?

I think, inline variables solved these problems. We still have issues
with global initialization order, but I don't see SCC/SCD solving them.
The mentioned above attributes do solve them to some extent, BTW.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4983ce2b-943a-f92e-16f1-4c22ec8fc846%40gmail.com.

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 19 Apr 2018 15:22:13 +0100
Raw View
--00000000000053ba38056a344cfd
Content-Type: text/plain; charset="UTF-8"

isn't this proposal the same as simply allowing:

class X {
  static bool init = initialise_class();
  static bool initialise_class() { ... }
};

?

Which I agree would be very useful, and indeed more versatile.

On 19 April 2018 at 13:54, Andrey Semashev <andrey.semashev@gmail.com>
wrote:

> On 04/19/18 13:37, Mariusz Moczala wrote:
>
>> Sure, with pleasure! lets call them SCC (Static Class Constructor) and
>> SCD (Static Class Destructor)
>> for simplification.
>>
>>
>> WHAT IS IT?
>>
>> SCC and SCD are special kind of constructor/destructor which is
>> associathed with class (type) rather
>> than with the object. What is certain from developers point of view is
>> that SCC is called only once
>> before entering the scope where corresponding type (class) is defined and
>> SCD once after leaving it.
>> When type is defined in global scope SCC is called once before execution
>> of main() function and SCD
>> once after.
>>
>
> Since the constructor/destructor in this case does not construct/destruct
> an object in this model, I don't see why it should be a
> constructor/destructor in the first place. The whole involvement of a type
> to define SCC/SCD looks like a kludge to me.
>
> If you want a function called on program startup or termination, you'd
> better look at standardizing __attribute__((constructor))/__attribute__((destructor))[1].
> You'd have to present a rationale for why a global variable with a
> constructor/destructor doesn't cut it and in the latter case - why
> std::atexit doesn't cut it.
>
> [1]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-
> Attributes.html#Common-Function-Attributes
>
> WHO NEED IT?
>>
>> Definitely those who write modern and header only libraries in C++. Every
>> year more and more libraries
>> are created as header only code. In such code to initialize some content
>> developers can for example
>> create a dedicated singleton class with special mechanisms for
>> initialization, unfortunately user of
>> the library have to manually execute this initialization. Developers of
>> the library can also provide
>> a lazy initialization, however not in every case it can be used. Using an
>> object declared as a global
>> variable is a nightmare in this case. It have to be initialized in only
>> one translation unit, so where
>> to put it? Definitely not in the header file as including it in many
>> translation units will lead to
>> fail linking. And moreover, where to put initialization of static class
>> members in header only code?
>>
>
> I think, inline variables solved these problems. We still have issues with
> global initialization order, but I don't see SCC/SCD solving them. The
> mentioned above attributes do solve them to some extent, BTW.
>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/a/is
> ocpp.org/d/msgid/std-proposals/4983ce2b-943a-f92e-16f1-
> 4c22ec8fc846%40gmail.com.
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1%3D6JiS53JdZ0oTUqCBTaVck3P-tmrRRD0RyGA%40mail.gmail.com.

--00000000000053ba38056a344cfd
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">isn&#39;t this proposal the same as simply allowing:<div><=
br></div><div><font face=3D"monospace, monospace">class X {</font></div><di=
v><font face=3D"monospace, monospace">=C2=A0 static bool init =3D initialis=
e_class();</font></div><div><font face=3D"monospace, monospace">=C2=A0 stat=
ic bool initialise_class() { ... }</font></div><div><font face=3D"monospace=
, monospace">};</font></div><div><br></div><div>?</div><div><br></div><div>=
Which I agree would be very useful, and indeed more versatile.</div></div><=
div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On 19 April 2018 a=
t 13:54, Andrey Semashev <span dir=3D"ltr">&lt;<a href=3D"mailto:andrey.sem=
ashev@gmail.com" target=3D"_blank">andrey.semashev@gmail.com</a>&gt;</span>=
 wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On 04/19/18 13:3=
7, Mariusz Moczala wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
Sure, with pleasure! lets call them SCC (Static Class Constructor) and SCD =
(Static Class Destructor)<br>
for simplification.<br>
<br>
<br>
WHAT IS IT?<br>
<br>
SCC and SCD are special kind of constructor/destructor which is associathed=
 with class (type) rather<br>
than with the object. What is certain from developers point of view is that=
 SCC is called only once<br>
before entering the scope where corresponding type (class) is defined and S=
CD once after leaving it.<br>
When type is defined in global scope SCC is called once before execution of=
 main() function and SCD<br>
once after.<br>
</blockquote>
<br></span>
Since the constructor/destructor in this case does not construct/destruct a=
n object in this model, I don&#39;t see why it should be a constructor/dest=
ructor in the first place. The whole involvement of a type to define SCC/SC=
D looks like a kludge to me.<br>
<br>
If you want a function called on program startup or termination, you&#39;d =
better look at standardizing __attribute__((constructor))/_<wbr>_attribute_=
_((destructor))[1]. You&#39;d have to present a rationale for why a global =
variable with a constructor/destructor doesn&#39;t cut it and in the latter=
 case - why std::atexit doesn&#39;t cut it.<br>
<br>
[1]: <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribut=
es.html#Common-Function-Attributes" rel=3D"noreferrer" target=3D"_blank">ht=
tps://gcc.gnu.org/onlinedocs<wbr>/gcc/Common-Function-<wbr>Attributes.html#=
Common-<wbr>Function-Attributes</a><span class=3D""><br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
WHO NEED IT?<br>
<br>
Definitely those who write modern and header only libraries in C++. Every y=
ear more and more libraries<br>
are created as header only code. In such code to initialize some content de=
velopers can for example<br>
create a dedicated singleton class with special mechanisms for initializati=
on, unfortunately user of<br>
the library have to manually execute this initialization. Developers of the=
 library can also provide<br>
a lazy initialization, however not in every case it can be used. Using an o=
bject declared as a global<br>
variable is a nightmare in this case. It have to be initialized in only one=
 translation unit, so where<br>
to put it? Definitely not in the header file as including it in many transl=
ation units will lead to<br>
fail linking. And moreover, where to put initialization of static class mem=
bers in header only code?<br>
</blockquote>
<br></span>
I think, inline variables solved these problems. We still have issues with =
global initialization order, but I don&#39;t see SCC/SCD solving them. The =
mentioned above attributes do solve them to some extent, BTW.<span class=3D=
""><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" target=3D=
"_blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4983ce2b-943a-f92e-16f1-4c22ec8fc846%=
40gmail.com" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com=
/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/4983ce2b-943a-f92e-16f1-<wbr>=
4c22ec8fc846%40gmail.com</a>.<br>
</blockquote></div><br></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1%3D6JiS53JdZ0oTUqCBTaV=
ck3P-tmrRRD0RyGA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1=
%3D6JiS53JdZ0oTUqCBTaVck3P-tmrRRD0RyGA%40mail.gmail.com</a>.<br />

--00000000000053ba38056a344cfd--

.


Author: Dilip Ranganathan <misc.usage@gmail.com>
Date: Thu, 19 Apr 2018 10:35:35 -0400
Raw View
--0000000000000eb21a056a347ce1
Content-Type: text/plain; charset="UTF-8"

One other language where I have seen static constructors is C#. But its
only used
to initialize static members and maybe perform some kind of one-time
initialization
before an instance of that type could be created (the timing of /when/ it
would be
run is a bit iffy though.)

On Thu, Apr 19, 2018 at 10:22 AM, Richard Hodges <hodges.r@gmail.com> wrote:

> isn't this proposal the same as simply allowing:
>
> class X {
>   static bool init = initialise_class();
>   static bool initialise_class() { ... }
> };
>
> ?
>
> Which I agree would be very useful, and indeed more versatile.
>
> On 19 April 2018 at 13:54, Andrey Semashev <andrey.semashev@gmail.com>
> wrote:
>
>> On 04/19/18 13:37, Mariusz Moczala wrote:
>>
>>> Sure, with pleasure! lets call them SCC (Static Class Constructor) and
>>> SCD (Static Class Destructor)
>>> for simplification.
>>>
>>>
>>> WHAT IS IT?
>>>
>>> SCC and SCD are special kind of constructor/destructor which is
>>> associathed with class (type) rather
>>> than with the object. What is certain from developers point of view is
>>> that SCC is called only once
>>> before entering the scope where corresponding type (class) is defined
>>> and SCD once after leaving it.
>>> When type is defined in global scope SCC is called once before execution
>>> of main() function and SCD
>>> once after.
>>>
>>
>> Since the constructor/destructor in this case does not construct/destruct
>> an object in this model, I don't see why it should be a
>> constructor/destructor in the first place. The whole involvement of a type
>> to define SCC/SCD looks like a kludge to me.
>>
>> If you want a function called on program startup or termination, you'd
>> better look at standardizing __attribute__((constructor))/__attribute__((destructor))[1].
>> You'd have to present a rationale for why a global variable with a
>> constructor/destructor doesn't cut it and in the latter case - why
>> std::atexit doesn't cut it.
>>
>> [1]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute
>> s.html#Common-Function-Attributes
>>
>> WHO NEED IT?
>>>
>>> Definitely those who write modern and header only libraries in C++.
>>> Every year more and more libraries
>>> are created as header only code. In such code to initialize some content
>>> developers can for example
>>> create a dedicated singleton class with special mechanisms for
>>> initialization, unfortunately user of
>>> the library have to manually execute this initialization. Developers of
>>> the library can also provide
>>> a lazy initialization, however not in every case it can be used. Using
>>> an object declared as a global
>>> variable is a nightmare in this case. It have to be initialized in only
>>> one translation unit, so where
>>> to put it? Definitely not in the header file as including it in many
>>> translation units will lead to
>>> fail linking. And moreover, where to put initialization of static class
>>> members in header only code?
>>>
>>
>> I think, inline variables solved these problems. We still have issues
>> with global initialization order, but I don't see SCC/SCD solving them. The
>> mentioned above attributes do solve them to some extent, BTW.
>>
>> --
>> 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.
>> To view this discussion on the web visit https://groups.google.com/a/is
>> ocpp.org/d/msgid/std-proposals/4983ce2b-943a-f92e-16f1-4c22e
>> c8fc846%40gmail.com.
>>
>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1%
> 3D6JiS53JdZ0oTUqCBTaVck3P-tmrRRD0RyGA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1%3D6JiS53JdZ0oTUqCBTaVck3P-tmrRRD0RyGA%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALEPxfuGjuH3zUGegpHx%2BJEPdp%2B4MDQ1VBuj9YR-Buse%3DX_keg%40mail.gmail.com.

--0000000000000eb21a056a347ce1
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">One other language where I have seen static constructors i=
s C#. But its only used<div>to initialize static members and maybe perform =
some kind of one-time initialization</div><div>before an instance of that t=
ype could be created (the timing of /when/ it would be<br></div><div>run is=
 a bit iffy though.)</div></div><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote">On Thu, Apr 19, 2018 at 10:22 AM, Richard Hodges <span dir=
=3D"ltr">&lt;<a href=3D"mailto:hodges.r@gmail.com" target=3D"_blank">hodges=
..r@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr">isn&#39;t this proposal the same as simply allowing:<div><br></d=
iv><div><font face=3D"monospace, monospace">class X {</font></div><div><fon=
t face=3D"monospace, monospace">=C2=A0 static bool init =3D initialise_clas=
s();</font></div><div><font face=3D"monospace, monospace">=C2=A0 static boo=
l initialise_class() { ... }</font></div><div><font face=3D"monospace, mono=
space">};</font></div><div><br></div><div>?</div><div><br></div><div>Which =
I agree would be very useful, and indeed more versatile.</div></div><div cl=
ass=3D"gmail_extra"><br><div class=3D"gmail_quote">On 19 April 2018 at 13:5=
4, Andrey Semashev <span dir=3D"ltr">&lt;<a href=3D"mailto:andrey.semashev@=
gmail.com" target=3D"_blank">andrey.semashev@gmail.com</a>&gt;</span> wrote=
:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><span>On 04/19/18 13:37, Mariusz Moczal=
a wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
Sure, with pleasure! lets call them SCC (Static Class Constructor) and SCD =
(Static Class Destructor)<br>
for simplification.<br>
<br>
<br>
WHAT IS IT?<br>
<br>
SCC and SCD are special kind of constructor/destructor which is associathed=
 with class (type) rather<br>
than with the object. What is certain from developers point of view is that=
 SCC is called only once<br>
before entering the scope where corresponding type (class) is defined and S=
CD once after leaving it.<br>
When type is defined in global scope SCC is called once before execution of=
 main() function and SCD<br>
once after.<br>
</blockquote>
<br></span>
Since the constructor/destructor in this case does not construct/destruct a=
n object in this model, I don&#39;t see why it should be a constructor/dest=
ructor in the first place. The whole involvement of a type to define SCC/SC=
D looks like a kludge to me.<br>
<br>
If you want a function called on program startup or termination, you&#39;d =
better look at standardizing __attribute__((constructor))/_<wbr>_attribute_=
_((destructor))[1]. You&#39;d have to present a rationale for why a global =
variable with a constructor/destructor doesn&#39;t cut it and in the latter=
 case - why std::atexit doesn&#39;t cut it.<br>
<br>
[1]: <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribut=
es.html#Common-Function-Attributes" rel=3D"noreferrer" target=3D"_blank">ht=
tps://gcc.gnu.org/onlinedocs<wbr>/gcc/Common-Function-Attribute<wbr>s.html#=
Common-Function-<wbr>Attributes</a><span><br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
WHO NEED IT?<br>
<br>
Definitely those who write modern and header only libraries in C++. Every y=
ear more and more libraries<br>
are created as header only code. In such code to initialize some content de=
velopers can for example<br>
create a dedicated singleton class with special mechanisms for initializati=
on, unfortunately user of<br>
the library have to manually execute this initialization. Developers of the=
 library can also provide<br>
a lazy initialization, however not in every case it can be used. Using an o=
bject declared as a global<br>
variable is a nightmare in this case. It have to be initialized in only one=
 translation unit, so where<br>
to put it? Definitely not in the header file as including it in many transl=
ation units will lead to<br>
fail linking. And moreover, where to put initialization of static class mem=
bers in header only code?<br>
</blockquote>
<br></span>
I think, inline variables solved these problems. We still have issues with =
global initialization order, but I don&#39;t see SCC/SCD solving them. The =
mentioned above attributes do solve them to some extent, BTW.<span class=3D=
"HOEnZb"><font color=3D"#888888"><span><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" target=3D=
"_blank">std-proposals+unsubscribe@isoc<wbr>pp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4983ce2b-943a-f92e-16f1-4c22ec8fc846%=
40gmail.com" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com=
/a/is<wbr>ocpp.org/d/msgid/std-proposals<wbr>/4983ce2b-943a-f92e-16f1-4c22e=
<wbr>c8fc846%40gmail.com</a>.<br>
</font></span></blockquote></div><span class=3D"HOEnZb"><font color=3D"#888=
888"><br></font></span></div><span class=3D"HOEnZb"><font color=3D"#888888"=
>

<p></p>

-- <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+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hYCedQmq1%3D6JiS53JdZ0oTUqCBTaV=
ck3P-tmrRRD0RyGA%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/st=
d-<wbr>proposals/CALvx3hYCedQmq1%<wbr>3D6JiS53JdZ0oTUqCBTaVck3P-<wbr>tmrRRD=
0RyGA%40mail.gmail.com</a>.<br>
</font></span></blockquote></div><br></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALEPxfuGjuH3zUGegpHx%2BJEPdp%2B4MDQ1=
VBuj9YR-Buse%3DX_keg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALEPxfuGju=
H3zUGegpHx%2BJEPdp%2B4MDQ1VBuj9YR-Buse%3DX_keg%40mail.gmail.com</a>.<br />

--0000000000000eb21a056a347ce1--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Thu, 19 Apr 2018 17:57:14 +0300
Raw View
On 04/19/18 17:22, Richard Hodges wrote:
> isn't this proposal the same as simply allowing:
>=20
> class X {
>  =C2=A0 static bool init =3D initialise_class();
>  =C2=A0 static bool initialise_class() { ... }
> };
>=20
> ?
>=20
> Which I agree would be very useful, and indeed more versatile.

Why not just initialize the static class members the usual way, with the=20
members' constructors? You can potentially leverage constexpr and make=20
the whole initialization a constant initialization.

Probably the only use case for initialise_class-style initialization is=20
building various process-wide tables or something like that. An empty=20
initializer class works fine for that use case, and I don't see how the=20
proposed feature improves on that.

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/44d9cc0d-0c54-11fb-6150-b224f10bc7f9%40gmail.com=
..

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 19 Apr 2018 12:10:43 -0700
Raw View
On Thursday, 19 April 2018 03:37:46 PDT Mariusz Moczala wrote:
> I encourage you to read more in old proposal available here:
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0421r0.html

Thanks.

Sorry, but I'm not convinced. The paper lists the following advantages:


>    There is no need to create dummy global variable to perform
initialization.

That's a non-issue.

>     Each dummy global variable used in initialization have associated
>     identifier and therefore is visible under IntelliSense. It becomes more
>     difficult in navigation for projects using multiple dummy global
>     variables.

Non-issue. You can easily hide the variables in a detail namespace.

Either way, both issues would be solved if we have the "discard identifier"
proposal accepted in one form or another.

>     Static constructors allows to perform early initialization for
>     headers-only libraries, where global variables cannot easily be used.

Isn't this solved by inline variables? The paper talks about it but does not
address why the use of inline variables would not obviate the need. I'd like
to ask for more exploration of the issue.

There's a side-point in the paper that suggests the static class constructor
could be the place to initialise the static members. This could help organise
code, but in the end it's not new functionality and the use-case already
works.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2100706.oicfcMmn2C%40tjmaciei-mobl1.

.