Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

POI of static data members and side-effects.

1,142 views
Skip to first unread message

litb

unread,
Jul 10, 2009, 6:11:18 PM7/10/09
to
Hello all. I have this example, and i'm not sure what output it should
show

struct C { C(int n) { printf("%d\n", n); } };

template<int N>
struct A {
static C c;
};

template<int N>
C A<N>::c(N);

// implicit instantiation of declarations, should have
// no effect on output
A<2> a2;
A<1> a1;

int main() {
A<1>::c; A<2>::c;
}

Should this output "1 2" or "2 1" or is the output order unspecified?
The part that is relevant, i think, is the following from 14.6.4.1/1

// snip
For a function template specialization, a member function template
specialization, or a specialization for a member function or static
data member of a class template, if the specialization is implicitly
instantiated because it is referenced from within another template
specialization and the context from which it is referenced depends on
a template parameter, the point of instantiation of the specialization
is the point of instantiation of the enclosing specialization.
Otherwise, the point of instantiation for such a specialization
immediately follows the namespace scope declaration or definition that
refers to the specialization.
// snap

I'm having a hard time figuring out the correct output. It seems to me
that output is unspecified, because the paragraph says that the POI of
both A<1>::c and A<2>::c is immediately after main (which is the
namespace scope definition that refers to it, of course). So both
would be instantiated immediately after main, and we can't have an
order.

But "Objects with static storage duration defined in namespace scope
in the same translation
unit and dynamically initialized shall be initialized in the order in
which their definition appears in the
translation unit. " (3.6.2/1). We have no order between the two, so
results are unspecified. Is that true?

Does "in the order which their definition appears" apply to static
data members of class templates at all? If not, how is the order be
defined in this case? I would be glad for any helps, thanks!

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Ron

unread,
Jul 11, 2009, 12:37:21 PM7/11/09
to
On Jul 10, 6:11 pm, litb <Schaub-Johan...@web.de> wrote:
> Hello all. I have this example, and i'm not sure what output it should
> show
>
> struct C { C(int n) { printf("%d\n", n); } };
>
> template<int N>
> struct A {
> static C c;
> };
>
> template<int N>
> C A<N>::c(N);
>
> // implicit instantiation of declarations, should have
> // no effect on output
> A<2> a2;
> A<1> a1;
>
> int main() {
> A<1>::c; A<2>::c;
> }
>
> Should this output "1 2" or "2 1" or is the output order unspecified?
> The part that is relevant, i think, is the following from 14.6.4.1/1
>


I believe you are right, it's unspecified. The point of
instantiation is back up outside of main and the same for
both. The standard appears to apply no requirement for
ordering.

Nick Hounsome

unread,
Jul 11, 2009, 12:35:08 PM7/11/09
to
On 10 July, 23:11, litb <Schaub-Johan...@web.de> wrote:
> Hello all. I have this example, and i'm not sure what output it should
> show
>
> struct C { C(int n) { printf("%d\n", n); } };
>
> template<int N>
> struct A {
> static C c;
> };
>
> template<int N>
> C A<N>::c(N);
>
> // implicit instantiation of declarations, should have
> // no effect on output

There is nothing implicit here.
You have created 2 global variables with static storage duration in a
single compilation unit and their constructors will therefore be
executed in order.

> A<2> a2;
> A<1> a1;
>
> int main() {
> A<1>::c; A<2>::c;

These are 2 variable references.
The compiler will generate no code for them (except possibly a
warning).
The output will come before this line and will be 2 then 1.

This is is essentialy the same as something like:

int x = 3;
int main() { x; }

Daniel Krügler

unread,
Jul 11, 2009, 12:36:05 PM7/11/09
to
On 11 Jul., 00:11, litb <Schaub-Johan...@web.de> wrote:
> Hello all. I have this example, and i'm not sure what output it should
> show
>
> struct C { C(int n) { printf("%d\n", n); } };
>
> template<int N>
> struct A {
> static C c;
> };
>
> template<int N>
> C A<N>::c(N);
>
> // implicit instantiation of declarations, should have
> // no effect on output
> A<2> a2;
> A<1> a1;
>
> int main() {
> A<1>::c; A<2>::c;
> }
>
> Should this output "1 2" or "2 1" or is the output order unspecified?

The order is unspecified, see below.

The intend is apply for static data members of class templates
as well. The current WP N2914 has refactored [basic.start.init]
as part of resolving

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#270
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#362
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#688

and made the position more clear, see p.2:

"[..] Static initialization shall be performed before any
dynamic initialization takes place. Dynamic initialization
of a non-local object with static storage duration is either
ordered or unordered. Definitions of explicitly specialized
class template static data members have ordered initialization.
Other class template static data members (i.e., implicitly
or explicitly instantiated specializations) have unordered
initialization. Other objects defined in namespace scope
have ordered initialization. Objects with ordered initialization
defined within a single translation unit shall be initialized
in the order of their definitions in the translation unit.[..]"

Note specifically that your example does *not* involve
a static initialization, because the constructor of
C does not fulfill the requirements of a constexpr
constructor. Note also that a relevant point of your example
is that you rely on implicit instantiation. So, to fix
the "unspecifity" you could provide explicit specializations
of the static data members.

HTH & Greetings from Bremen,

Daniel Kr�gler

litb

unread,
Jul 12, 2009, 7:56:47 AM7/12/09
to
On 11 Jul., 18:36, Daniel Kr�gler <daniel.krueg...@googlemail.com>
wrote:

> On 11 Jul., 00:11, litb <Schaub-Johan...@web.de> wrote:
> > Does "in the order which their definition appears" apply to static
> > data members of class templates at all? If not, how is the order be
> > defined in this case? I would be glad for any helps, thanks!
>
> The intend is apply for static data members of class templates
> as well. The current WP N2914 has refactored [basic.start.init]
> as part of resolving
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#270 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#362 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#688
>
Thanks, nice discussions. I did not know the passages referring to
"translation unit" does not generally apply to instantiated entities.
Now it also makes sense to me how the ODR says that no TU can contain
more than one definition of most things, but we can still have more
than one POI of non-class entities. This is because TU != IU, as i
understand it now.

> and made the position more clear, see p.2:
>
> "[..] Static initialization shall be performed before any
> dynamic initialization takes place. Dynamic initialization
> of a non-local object with static storage duration is either
> ordered or unordered. Definitions of explicitly specialized
> class template static data members have ordered initialization.
> Other class template static data members (i.e., implicitly
> or explicitly instantiated specializations) have unordered
> initialization. Other objects defined in namespace scope
> have ordered initialization. Objects with ordered initialization
> defined within a single translation unit shall be initialized
> in the order of their definitions in the translation unit.[..]"
>

I solved the issue by providing an explicit instantiation not knowing
about the IU distinction :) But i think explicit specialization of it
isn't too bad either here, so i will use that.

Thanks for your reply, provided lots of insight.

0 new messages