Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How to write a library with a static object?

Reply
Thread Tools

How to write a library with a static object?

 
 
Jeroen
Guest
Posts: n/a
 
      03-05-2007
Hi all,

I've got a question about writing a library. Let me characterize that
library by the following:

* there is a class A which is available to the user
* there is a class B that is used in severel 'underwater operations'
* there is a list which stores objects of class B

There are several issues I'm not sure about:

* Is it best practice to put everything in hpp-files, so no cpp file is
used (#include is al you need to use the lib)?
* How do I get an instance of the list? It should always be available to
my library. Is it wise to have a class C in the hpp-file with static
member 'list<class_B> my_list;' which provides me my list? Or is there a
better way to do so...

Regards,

Jeroen
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      03-05-2007
Jeroen wrote:
> Hi all,
>
> I've got a question about writing a library. Let me characterize that
> library by the following:
>
> * there is a class A which is available to the user
> * there is a class B that is used in severel 'underwater operations'
> * there is a list which stores objects of class B
>
> There are several issues I'm not sure about:
>
> * Is it best practice to put everything in hpp-files, so no cpp file is
> used (#include is al you need to use the lib)?


It's a possibility. Main issue I guess would be increased compile time
for your users if you have a lot of code.

> * How do I get an instance of the list? It should always be available to
> my library. Is it wise to have a class C in the hpp-file with static
> member 'list<class_B> my_list;' which provides me my list? Or is there a
> better way to do so...


The big issue here is the 'static initialisation order fiasco'. There's
no perfect answer but having your list as a static member of a global
function is the best you can do. See here

http://www.parashift.com/c++-faq-lit...html#faq-10.12

>
> Regards,
>
> Jeroen


john
 
Reply With Quote
 
 
 
 
Jeroen
Guest
Posts: n/a
 
      03-05-2007
John Harrison wrote:

> Jeroen wrote:
>
>> Hi all,
>>
>> I've got a question about writing a library. Let me characterize that
>> library by the following:
>>
>> * there is a class A which is available to the user
>> * there is a class B that is used in severel 'underwater operations'
>> * there is a list which stores objects of class B
>>
>> There are several issues I'm not sure about:
>>
>> * Is it best practice to put everything in hpp-files, so no cpp file
>> is used (#include is al you need to use the lib)?

>
>
> It's a possibility. Main issue I guess would be increased compile time
> for your users if you have a lot of code.
>
>> * How do I get an instance of the list? It should always be available
>> to my library. Is it wise to have a class C in the hpp-file with
>> static member 'list<class_B> my_list;' which provides me my list? Or
>> is there a better way to do so...

>
>
> The big issue here is the 'static initialisation order fiasco'.
> There's no perfect answer but having your list as a static member of a
> global function is the best you can do. See here
>
> http://www.parashift.com/c++-faq-lit...html#faq-10.12
>
>>
>> Regards,
>>
>> Jeroen

>
>
> john


OK, thanx. Very helpfull to read the link. Let me try a better
construction: if I go back to my code (yet to write...), then I have:

* class A that's available to the user
* class B that is used 'underwater', but only if the user does
something with class A
* a list for objects of class B (only accessed if the user does
something with class A...)

So maybe I am safe if I put the list as a static member of class A?

class B {
int blah;
};

class A {
private:
static list<B> my_list;
static void put_B_in_the_list(const B& b);
static B& find_B_in_the_list(int blah);

int more_blah;
};

Given the fact that the list is only accessed if the user of the library
uses class A, this should prevent the init fiasco described in the link
you gave?

Thanx again,

Jeroen
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      03-05-2007
Jeroen wrote:
> John Harrison wrote:
>
>> Jeroen wrote:
>>
>>> Hi all,
>>>
>>> I've got a question about writing a library. Let me characterize that
>>> library by the following:
>>>
>>> * there is a class A which is available to the user
>>> * there is a class B that is used in severel 'underwater operations'
>>> * there is a list which stores objects of class B
>>>
>>> There are several issues I'm not sure about:
>>>
>>> * Is it best practice to put everything in hpp-files, so no cpp file
>>> is used (#include is al you need to use the lib)?

>>
>>
>>
>> It's a possibility. Main issue I guess would be increased compile time
>> for your users if you have a lot of code.
>>
>>> * How do I get an instance of the list? It should always be available
>>> to my library. Is it wise to have a class C in the hpp-file with
>>> static member 'list<class_B> my_list;' which provides me my list? Or
>>> is there a better way to do so...

>>
>>
>>
>> The big issue here is the 'static initialisation order fiasco'.
>> There's no perfect answer but having your list as a static member of a
>> global function is the best you can do. See here
>>
>> http://www.parashift.com/c++-faq-lit...html#faq-10.12
>>
>>>
>>> Regards,
>>>
>>> Jeroen

>>
>>
>>
>> john

>
>
> OK, thanx. Very helpfull to read the link. Let me try a better
> construction: if I go back to my code (yet to write...), then I have:
>
> * class A that's available to the user
> * class B that is used 'underwater', but only if the user does
> something with class A
> * a list for objects of class B (only accessed if the user does
> something with class A...)
>
> So maybe I am safe if I put the list as a static member of class A?
>
> class B {
> int blah;
> };
>
> class A {
> private:
> static list<B> my_list;
> static void put_B_in_the_list(const B& b);
> static B& find_B_in_the_list(int blah);
>
> int more_blah;
> };
>
> Given the fact that the list is only accessed if the user of the library
> uses class A, this should prevent the init fiasco described in the link
> you gave?
>
> Thanx again,
>
> Jeroen


No, if your user attempts to use class A in the construction of a global
object there is no guarantee that my_list will have been constructed.
You only get that guarantee by putting my_list as a static in a global
function as shown in the FAQ.

john
 
Reply With Quote
 
Jeroen
Guest
Posts: n/a
 
      03-06-2007
John Harrison schreef:
> Jeroen wrote:
>> John Harrison wrote:
>>
>>> Jeroen wrote:
>>>
>>>> Hi all,
>>>>
>>>> I've got a question about writing a library. Let me characterize
>>>> that library by the following:
>>>>
>>>> * there is a class A which is available to the user
>>>> * there is a class B that is used in severel 'underwater operations'
>>>> * there is a list which stores objects of class B
>>>>
>>>> There are several issues I'm not sure about:
>>>>
>>>> * Is it best practice to put everything in hpp-files, so no cpp file
>>>> is used (#include is al you need to use the lib)?
>>>
>>>
>>>
>>> It's a possibility. Main issue I guess would be increased compile
>>> time for your users if you have a lot of code.
>>>
>>>> * How do I get an instance of the list? It should always be
>>>> available to my library. Is it wise to have a class C in the
>>>> hpp-file with static member 'list<class_B> my_list;' which provides
>>>> me my list? Or is there a better way to do so...
>>>
>>>
>>>
>>> The big issue here is the 'static initialisation order fiasco'.
>>> There's no perfect answer but having your list as a static member of
>>> a global function is the best you can do. See here
>>>
>>> http://www.parashift.com/c++-faq-lit...html#faq-10.12
>>>
>>>>
>>>> Regards,
>>>>
>>>> Jeroen
>>>
>>>
>>>
>>> john

>>
>>
>> OK, thanx. Very helpfull to read the link. Let me try a better
>> construction: if I go back to my code (yet to write...), then I have:
>>
>> * class A that's available to the user
>> * class B that is used 'underwater', but only if the user does
>> something with class A
>> * a list for objects of class B (only accessed if the user does
>> something with class A...)
>>
>> So maybe I am safe if I put the list as a static member of class A?
>>
>> class B {
>> int blah;
>> };
>>
>> class A {
>> private:
>> static list<B> my_list;
>> static void put_B_in_the_list(const B& b);
>> static B& find_B_in_the_list(int blah);
>>
>> int more_blah;
>> };
>>
>> Given the fact that the list is only accessed if the user of the
>> library uses class A, this should prevent the init fiasco described in
>> the link you gave?
>>
>> Thanx again,
>>
>> Jeroen

>
> No, if your user attempts to use class A in the construction of a global
> object there is no guarantee that my_list will have been constructed.
> You only get that guarantee by putting my_list as a static in a global
> function as shown in the FAQ.
>
> john


OK, thanks John. I found that also in the FAQ. I'm not really sure if a
global function in the hpp-file may cause a problem if that hpp-file is
included in multiple source files of a project, but I can switch to the
static member-function holding the static list-pointer as shown in 10.16
of the FAQ.

Jeroen
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      03-06-2007
Jeroen wrote:
> John Harrison schreef:
>
>> Jeroen wrote:
>>
>>> John Harrison wrote:
>>>
>>>> Jeroen wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> I've got a question about writing a library. Let me characterize
>>>>> that library by the following:
>>>>>
>>>>> * there is a class A which is available to the user
>>>>> * there is a class B that is used in severel 'underwater operations'
>>>>> * there is a list which stores objects of class B
>>>>>
>>>>> There are several issues I'm not sure about:
>>>>>
>>>>> * Is it best practice to put everything in hpp-files, so no cpp
>>>>> file is used (#include is al you need to use the lib)?
>>>>
>>>>
>>>>
>>>>
>>>> It's a possibility. Main issue I guess would be increased compile
>>>> time for your users if you have a lot of code.
>>>>
>>>>> * How do I get an instance of the list? It should always be
>>>>> available to my library. Is it wise to have a class C in the
>>>>> hpp-file with static member 'list<class_B> my_list;' which provides
>>>>> me my list? Or is there a better way to do so...
>>>>
>>>>
>>>>
>>>>
>>>> The big issue here is the 'static initialisation order fiasco'.
>>>> There's no perfect answer but having your list as a static member of
>>>> a global function is the best you can do. See here
>>>>
>>>> http://www.parashift.com/c++-faq-lit...html#faq-10.12
>>>>
>>>>>
>>>>> Regards,
>>>>>
>>>>> Jeroen
>>>>
>>>>
>>>>
>>>>
>>>> john
>>>
>>>
>>>
>>> OK, thanx. Very helpfull to read the link. Let me try a better
>>> construction: if I go back to my code (yet to write...), then I have:
>>>
>>> * class A that's available to the user
>>> * class B that is used 'underwater', but only if the user does
>>> something with class A
>>> * a list for objects of class B (only accessed if the user does
>>> something with class A...)
>>>
>>> So maybe I am safe if I put the list as a static member of class A?
>>>
>>> class B {
>>> int blah;
>>> };
>>>
>>> class A {
>>> private:
>>> static list<B> my_list;
>>> static void put_B_in_the_list(const B& b);
>>> static B& find_B_in_the_list(int blah);
>>>
>>> int more_blah;
>>> };
>>>
>>> Given the fact that the list is only accessed if the user of the
>>> library uses class A, this should prevent the init fiasco described
>>> in the link you gave?
>>>
>>> Thanx again,
>>>
>>> Jeroen

>>
>>
>> No, if your user attempts to use class A in the construction of a
>> global object there is no guarantee that my_list will have been
>> constructed. You only get that guarantee by putting my_list as a
>> static in a global function as shown in the FAQ.
>>
>> john

>
>
> OK, thanks John. I found that also in the FAQ. I'm not really sure if a
> global function in the hpp-file may cause a problem if that hpp-file is
> included in multiple source files of a project, but I can switch to the
> static member-function holding the static list-pointer as shown in 10.16
> of the FAQ.
>
> Jeroen


A global function would not be a problem if it was declared inline. Same
holds for a static member function, it must be (explicitly or
implicitly) declared inline.

john
 
Reply With Quote
 
Adrian Hawryluk
Guest
Posts: n/a
 
      03-07-2007
John Harrison wrote:
> Jeroen wrote:
>> OK, thanx. Very helpfull to read the link. Let me try a better
>> construction: if I go back to my code (yet to write...), then I have:
>>
>> * class A that's available to the user
>> * class B that is used 'underwater', but only if the user does
>> something with class A
>> * a list for objects of class B (only accessed if the user does
>> something with class A...)
>>
>> So maybe I am safe if I put the list as a static member of class A?
>>
>> class B {
>> int blah;
>> };
>>
>> class A {
>> private:
>> static list<B> my_list;
>> static void put_B_in_the_list(const B& b);
>> static B& find_B_in_the_list(int blah);
>>
>> int more_blah;
>> };
>>
>> Given the fact that the list is only accessed if the user of the
>> library uses class A, this should prevent the init fiasco described in
>> the link you gave?
>>
>> Thanx again,
>>
>> Jeroen

>
> No, if your user attempts to use class A in the construction of a global
> object there is no guarantee that my_list will have been constructed.
> You only get that guarantee by putting my_list as a static in a global
> function as shown in the FAQ.
>
> john


Excuse me, but does anyone know why this fiasco even exist? Why is
there not some dependency mechanism in place? Or something like the
static local object being constructed when the control flows to them (as
opposed to over them)?

One other thing. In that FAQ we have Fred defined as so:

// File x.cpp

#include "Fred.h"

Fred& x()
{
static Fred* ans = new Fred();
return *ans;
}


Why is it not defined like this:

// File x.cpp

#include "Fred.h"

Fred& x()
{
static Fred ans;
return &ans;
}

It looks to me that the compilers are built pretty flimsily.


Adrian
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      03-07-2007
Adrian Hawryluk wrote:
> John Harrison wrote:
>
>> Jeroen wrote:
>>
>>> OK, thanx. Very helpfull to read the link. Let me try a better
>>> construction: if I go back to my code (yet to write...), then I have:
>>>
>>> * class A that's available to the user
>>> * class B that is used 'underwater', but only if the user does
>>> something with class A
>>> * a list for objects of class B (only accessed if the user does
>>> something with class A...)
>>>
>>> So maybe I am safe if I put the list as a static member of class A?
>>>
>>> class B {
>>> int blah;
>>> };
>>>
>>> class A {
>>> private:
>>> static list<B> my_list;
>>> static void put_B_in_the_list(const B& b);
>>> static B& find_B_in_the_list(int blah);
>>>
>>> int more_blah;
>>> };
>>>
>>> Given the fact that the list is only accessed if the user of the
>>> library uses class A, this should prevent the init fiasco described
>>> in the link you gave?
>>>
>>> Thanx again,
>>>
>>> Jeroen

>>
>>
>> No, if your user attempts to use class A in the construction of a
>> global object there is no guarantee that my_list will have been
>> constructed. You only get that guarantee by putting my_list as a
>> static in a global function as shown in the FAQ.
>>
>> john

>
>
> Excuse me, but does anyone know why this fiasco even exist? Why is
> there not some dependency mechanism in place? Or something like the
> static local object being constructed when the control flows to them (as
> opposed to over them)?


It's a good question. One issue would be that with such a scheme the
order of initialisation would be unpredictable, and that wouldn't mesh
well with the one guarantee that the standard does give, which is that
definitions within a single file are initialised in the order that they
occur in that file. I know at times I found that certainty to be useful.

There may be reasons why what you're suggesting isn't easy to achieve, I
don't know, but representatives of the major compiler wiriters work on
the C++ standards board so they wouldn't have decided on this fiasco
with out good reason.


>
> One other thing. In that FAQ we have Fred defined as so:
>
> // File x.cpp
>
> #include "Fred.h"
>
> Fred& x()
> {
> static Fred* ans = new Fred();
> return *ans;
> }
>
>
> Why is it not defined like this:
>
> // File x.cpp
>
> #include "Fred.h"
>
> Fred& x()
> {
> static Fred ans;
> return &ans;
> }
>


If you read FAQ 10.14 he explains why the pointer is used. Personally I
think the issue raised in that FAQ is more of a theoretical concern, I
never been bitten by it in practise (unlike the initalisation order fiasco).


> It looks to me that the compilers are built pretty flimsily.
>
>
> Adrian

 
Reply With Quote
 
Adrian Hawryluk
Guest
Posts: n/a
 
      03-07-2007
John Harrison wrote:
> Adrian Hawryluk wrote:
>>
>> Excuse me, but does anyone know why this fiasco even exist? Why is
>> there not some dependency mechanism in place? Or something like the
>> static local object being constructed when the control flows to them
>> (as opposed to over them)?

>
> It's a good question. One issue would be that with such a scheme the
> order of initialisation would be unpredictable, and that wouldn't mesh
> well with the one guarantee that the standard does give, which is that
> definitions within a single file are initialised in the order that they
> occur in that file. I know at times I found that certainty to be useful.


I wasn't saying that order of initialisation as they occur in the source
file should change. I ment that the order of initilisation in the group
of different source files should change based on the dependency of one
source file to another. It seems reasonable and doable. 'make' can do
it based on these dependencies (when given that some compilers can spit
out dependencies based on the included files).

> There may be reasons why what you're suggesting isn't easy to achieve, I
> don't know, but representatives of the major compiler wiriters work on
> the C++ standards board so they wouldn't have decided on this fiasco
> with out good reason.


Sounds like they're lazy.

>>
>> One other thing. In that FAQ we have Fred defined as so:
>>
>> // File x.cpp
>>
>> #include "Fred.h"
>>
>> Fred& x()
>> {
>> static Fred* ans = new Fred();
>> return *ans;
>> }
>>
>>
>> Why is it not defined like this:
>>
>> // File x.cpp
>>
>> #include "Fred.h"
>>
>> Fred& x()
>> {
>> static Fred ans;
>> return &ans;
>> }
>>

>
> If you read FAQ 10.14...


Hmm, should have read a little further.

> ...he explains why the pointer is used. Personally I
> think the issue raised in that FAQ is more of a theoretical concern, I
> never been bitten by it in practise (unlike the initalisation order
> fiasco).


This just sounds like another dependency issue. Argh, its sooooo doable.

>> It looks to me that the compilers are built pretty flimsily.


I noticed you didn't say anything about that, but left it in all the
same.


Adrian
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      03-08-2007
Adrian Hawryluk wrote:
> John Harrison wrote:
>
>> Adrian Hawryluk wrote:
>>
>>>
>>> Excuse me, but does anyone know why this fiasco even exist? Why is
>>> there not some dependency mechanism in place? Or something like the
>>> static local object being constructed when the control flows to them
>>> (as opposed to over them)?

>>
>>
>> It's a good question. One issue would be that with such a scheme the
>> order of initialisation would be unpredictable, and that wouldn't mesh
>> well with the one guarantee that the standard does give, which is that
>> definitions within a single file are initialised in the order that
>> they occur in that file. I know at times I found that certainty to be
>> useful.

>
>
> I wasn't saying that order of initialisation as they occur in the source
> file should change. I ment that the order of initilisation in the group
> of different source files should change based on the dependency of one
> source file to another. It seems reasonable and doable. 'make' can do
> it based on these dependencies (when given that some compilers can spit
> out dependencies based on the included files).


That can't work, for one thing dependencies only occur at runtime, they
can't be worked out in advance. Possible for constructors to contain if
statements so a compiler or linker doesn't know which branch of the if
statement will be taken and so can't work out which globals are
dependent on which.

Secondly it's perfectly possible for files to be mutally dependendent.
One global in one file requires another global in a second file, but a
different global in that second file requires yet another global in the
first file.

>
>> There may be reasons why what you're suggesting isn't easy to achieve,
>> I don't know, but representatives of the major compiler wiriters work
>> on the C++ standards board so they wouldn't have decided on this
>> fiasco with out good reason.

>
>
> Sounds like they're lazy.


I think you're underestimating the problem.

>


john
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
static library and dynamic library Even C Programming 6 10-20-2007 04:05 PM
Static library Vs. Dynamic library iceColdFire C++ 3 05-17-2005 06:16 AM
how to link static library to another static libraries free2cric@yahoo.com C++ 2 05-16-2005 04:40 PM
Dynamic Library or Static Library under Linux gouqizi.lvcha@gmail.com C++ 6 05-10-2005 03:16 PM



Advertisments