 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
benben Guest
|
Posted: Thu Feb 23, 2006 1:06 pm Post subject: construction of static member of a class template |
|
|
Hi All!
Consider the following code snippet:
#include <iostream>
#include <string>
struct type_record
{
type_record(const std::string& str)
{
std::cout << str << "\n";
}
};
template <typename T>
class helper
{
private: // nothing uses the following member
volatile static type_record reg;
};
template <typename T>
volatile type_record
helper<T>::reg(typeid(T).name());
template class helper<int>;
template class helper<float>;
template class helper<double>;
int main(){}
I have compiled the above code and I would like to have some firm answer
for the following questions:
1. Does the C++ standard guarantee that the constructor
register::register is called for all of the following objects:
- helper<int>::reg;
- helper<float>::reg;
- helper<double>::reg;
2. Is the the decorator "volatile" appropriate above? In other words,
had it been absent, is there a chance that the compiler would optimizes
helper<T>::reg member away when nothing in the compilation unit ever
uses the member?
3. I used standard stream and string facilities in the code before
main() is executed. Does the C++ standard guarantee that dependent
libraries are initialized prior to the initialization of any depending
library?
Any hint is greatly appreciated!
Yours,
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
benben Guest
|
Posted: Thu Feb 23, 2006 3:06 pm Post subject: Re: construction of static member of a class template |
|
|
| Quote: | 1. Does the C++ standard guarantee that the constructor
register::register is called for all of the following objects:
|
By register::register I really meant type_record::type_record. That was
the name I used first time and it turned out to be a keyword (that I
never used,) but the name stuck in my head.
My apologies,
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Thu Feb 23, 2006 7:06 pm Post subject: Re: construction of static member of a class template |
|
|
benben wrote:
| Quote: | 1. Does the C++ standard guarantee that the constructor
register::register is called for all of the following objects:
By register::register I really meant type_record::type_record. That was
the name I used first time and it turned out to be a keyword (that I
never used,) but the name stuck in my head.
My apologies,
Ben
|
1. The constructor will always be called.
2. Objects declared as volatile are not used in optimizations because
their value can change at any time.
3. I am not clear about this question. It would be helpful if you can
explain with an example.
But my guess if your question is e.g., in iostream class is
derived from ostream and istream then whether you should include
ostream.h and istream.h before including iostream.h in your cpp file?
then answer is no. C++ does guarantee that "guarantee that dependent
libraries are initialized prior to the initialization of any depending
library"
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Feb 24, 2006 10:06 am Post subject: Re: construction of static member of a class template |
|
|
subhadeep.sniogi (AT) patni (DOT) com wrote:
| Quote: | benben wrote:
But my guess if your question is e.g., in iostream class is
derived from ostream and istream then whether you should include
ostream.h and istream.h before including iostream.h in your cpp file?
|
It sounds more like he is talking about the order of
initialization of objects defined at namespace scope.
Also, FWIW: the class std::iostream is defined in the header
<istream>, not in <iostream>. According to the standard, the
header <iostream> only declares the eight standard objects.
Declares, not defines, so you cannot actually do anything with
the objects without including the header which defines the class
of the object, <istream> or <ostream>. (In practice, most if
not all implementations have made <iostream> a more or less
drop-in replacement for the classical <iostream.h>.)
And of course, there is no header istream.h nor ostream.h, nor
has there ever been.
| Quote: | then answer is no. C++ does guarantee that "guarantee that
dependent libraries are initialized prior to the
initialization of any depending library"
|
Where do you find that. All I can find is (§3.6.2/1): "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." Nothing about the order between
translation units (which is, as far as I know, unspecified).
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Feb 24, 2006 10:06 am Post subject: Re: construction of static member of a class template |
|
|
benben wrote:
| Quote: | Consider the following code snippet:
#include <iostream
#include <string
struct type_record
{
type_record(const std::string& str)
{
std::cout << str << "\n";
}
};
template <typename T
class helper
{
private: // nothing uses the following member
volatile static type_record reg;
};
template <typename T
volatile type_record
helper<T>::reg(typeid(T).name());
template class helper<int>;
template class helper<float>;
template class helper<double>;
int main(){}
I have compiled the above code and I would like to have some
firm answer for the following questions:
1. Does the C++ standard guarantee that the constructor
register::register is called for all of the following objects:
- helper<int>::reg;
- helper<float>::reg;
- helper<double>::reg;
|
Yes.
| Quote: | 2. Is the the decorator "volatile" appropriate above?
|
No.
| Quote: | In other words, had it been absent, is there a chance that the
compiler would optimizes helper<T>::reg member away when
nothing in the compilation unit ever uses the member?
|
If the object has a non-trivial constructor, it cannot be
eliminated. (There are a few special exceptions, but they only
involve eliminating copies of an existing object.)
| Quote: | 3. I used standard stream and string facilities in the code
before main() is executed. Does the C++ standard guarantee
that dependent libraries are initialized prior to the
initialization of any depending library?
|
No.
In the case of iostream objects, you can force initialization
before use, by creating an instance of an std::ios::Init.
You seem to be assuming the typical implementation of
<iostream>, rather than the minimum required by the standard.
In the typical implementation, <iostream> is a direct
replacement for <iostream.h>, and <iostream.h> contained a
static definition of the equivalent of std::ios::Init. So you
should be safe here in practice -- your code actually contains
undefined behavior, but with a minimum implementation of
<iostream>, it won't compile.
If you want to be strictly conformant, only counting on what is
guaranteed by the standard, you must add an include of
<ostream>, and you must define an instance of std::ios::Init
somewhere. Strictly speaking, too, the order of initialization
of template instantiations isn't defined, so you cannot count on
a static instance defined before your explicit instantiations;
the safest solution is probably to define it as a local static
in the constructor of your type_record object.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Guest
|
Posted: Sat Feb 25, 2006 12:06 pm Post subject: Re: construction of static member of a class template |
|
|
kanze wrote:
| Quote: | subhadeep.sniogi (AT) patni (DOT) com wrote:
benben wrote:
But my guess if your question is e.g., in iostream class is
derived from ostream and istream then whether you should include
ostream.h and istream.h before including iostream.h in your cpp file?
It sounds more like he is talking about the order of
initialization of objects defined at namespace scope.
Also, FWIW: the class std::iostream is defined in the header
istream>, not in <iostream>. According to the standard, the
header <iostream> only declares the eight standard objects.
Declares, not defines, so you cannot actually do anything with
the objects without including the header which defines the class
of the object, <istream> or <ostream>. (In practice, most if
not all implementations have made <iostream> a more or less
drop-in replacement for the classical <iostream.h>.)
And of course, there is no header istream.h nor ostream.h, nor
has there ever been.
then answer is no. C++ does guarantee that "guarantee that
dependent libraries are initialized prior to the
initialization of any depending library"
Where do you find that. All I can find is (§3.6.2/1): "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." Nothing about the order between
translation units (which is, as far as I know, unspecified).
|
I am really sorry. I have started learning C++ past 4 months only and I
was trying to reply to the mail as I thought the question is too easy(I
was previuosly in COBOL programming). But now I know I am wrong. Thank
you kanze. I promise I will not try to give any "expert" opinion as a
"4 month" old C++ programmer again in the future until I am absolutely
sure about the answer. Anyway I have learned more from this forum than
I could have by just studying a book.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
benben Guest
|
Posted: Sat Feb 25, 2006 12:06 pm Post subject: Re: construction of static member of a class template |
|
|
| Quote: | If the object has a non-trivial constructor, it cannot be
eliminated. (There are a few special exceptions, but they only
involve eliminating copies of an existing object.)
|
Would you go on to explain what are those exceptions? A pointer to a
book chapter or a web page would be appreciated!
| Quote: | 3. I used standard stream and string facilities in the code
before main() is executed. Does the C++ standard guarantee
that dependent libraries are initialized prior to the
initialization of any depending library?
No.
In the case of iostream objects, you can force initialization
before use, by creating an instance of an std::ios::Init.
|
I searched for a while but I couldn't find anything written on
std::ios::Init. What I did find is something like std::ios::init_type.
Is this what you were talking about? Or am I totally mistaken?
| Quote: |
You seem to be assuming the typical implementation of
iostream>, rather than the minimum required by the standard.
In the typical implementation, <iostream> is a direct
replacement for <iostream.h>, and <iostream.h> contained a
static definition of the equivalent of std::ios::Init. So you
should be safe here in practice -- your code actually contains
undefined behavior, but with a minimum implementation of
iostream>, it won't compile.
If you want to be strictly conformant, only counting on what is
guaranteed by the standard, you must add an include of
ostream>, and you must define an instance of std::ios::Init
somewhere. Strictly speaking, too, the order of initialization
of template instantiations isn't defined, so you cannot count on
a static instance defined before your explicit instantiations;
the safest solution is probably to define it as a local static
in the constructor of your type_record object.
|
Thanks for the great answers. My real problem is I am trying to write a
library to do some work prior to the execution of main(). However, if
there is no guarantee that at that point time any library is initialized
properly my solution won't be able to work because it uses other
libraries before main().
It is most unlikely I would use the iostream library. But I would use
things like containers and RTTI. I assume that these libraries do not
define any non-trivial global or namespace objects so it is safe to
assume these libraries can be used anywhere before main()?
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|