Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #10794 > unrolled thread

static member linker problem

Started byPhilipp Kraus <philipp.kraus@flashpixx.de>
First post2011-10-11 14:53 +0200
Last post2011-10-11 17:29 +0100
Articles 8 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  static member linker problem Philipp Kraus <philipp.kraus@flashpixx.de> - 2011-10-11 14:53 +0200
    Re: static member linker problem Juha Nieminen <nospam@thanks.invalid> - 2011-10-11 12:58 +0000
      Re: static member linker problem Philipp Kraus <philipp.kraus@flashpixx.de> - 2011-10-11 15:10 +0200
    Re: static member linker problem Victor Bazarov <v.bazarov@comcast.invalid> - 2011-10-11 09:45 -0400
      Re: static member linker problem "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-10-11 17:24 +0200
    Re: static member linker problem "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-10-11 17:26 +0200
      Re: static member linker problem Victor Bazarov <v.bazarov@comcast.invalid> - 2011-10-11 12:17 -0400
        Re: static member linker problem Leigh Johnston <leigh@i42.co.uk> - 2011-10-11 17:29 +0100

#10794 — static member linker problem

FromPhilipp Kraus <philipp.kraus@flashpixx.de>
Date2011-10-11 14:53 +0200
Subjectstatic member linker problem
Message-ID<j71e8t$tul$1@online.de>
Hello,

I have written a header-only class with inline calls like in a header 
file only like:

--header.hpp---
class myclass {

    public :

    private :
         static anotherclass obj;
}

No i do the initialization in the same header file:
anotherclass myclass::obj;

If I include this header in one cpp of another project, everything 
works fine, but if the projects has more than one cpp
file, that includes the header, I get the linker error, that there are 
duplicated calls for the myclass::obj part.
I can create a cpp file with the initialization, but is there a 
"header-only" solution to do the initialization without
linker problems eg a design pattern or anything else? My goal the 
static members should be initialize within
their header file and the header files can be include more than once.

Thanks

Phil

[toc] | [next] | [standalone]


#10795

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-10-11 12:58 +0000
Message-ID<4e943d70$0$3064$7b1e8fa0@news.nbl.fi>
In reply to#10794
Philipp Kraus <philipp.kraus@flashpixx.de> wrote:
> I can create a cpp file with the initialization, but is there a 
> "header-only" solution to do the initialization without
> linker problems eg a design pattern or anything else?

  C++ does not support instantiating static members "inline" in the same
way as function definitions, except for templates (where the "inlineness"
is implicit).

  Either you have to use a compilation unit for the static member, or
you have to make the class templated.

[toc] | [prev] | [next] | [standalone]


#10796

FromPhilipp Kraus <philipp.kraus@flashpixx.de>
Date2011-10-11 15:10 +0200
Message-ID<j71f8a$uog$1@online.de>
In reply to#10795
On 2011-10-11 14:58:24 +0200, Juha Nieminen said:

> Philipp Kraus <philipp.kraus@flashpixx.de> wrote:
>> I can create a cpp file with the initialization, but is there a
>> "header-only" solution to do the initialization without
>> linker problems eg a design pattern or anything else?
> 
>   C++ does not support instantiating static members "inline" in the same
> way as function definitions, except for templates (where the "inlineness"
> is implicit).
> 
>   Either you have to use a compilation unit for the static member, or
> you have to make the class templated.

I think a own compilation unit is the best way, because there are only 
two classes
with static members, that are not templated

Thanks

Phil

[toc] | [prev] | [next] | [standalone]


#10798

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-10-11 09:45 -0400
Message-ID<j71h9a$pn1$1@dont-email.me>
In reply to#10794
On 10/11/2011 8:53 AM, Philipp Kraus wrote:
> I have written a header-only class with inline calls like in a header
> file only like:
>
> --header.hpp---
> class myclass {
>
> public :
>
> private :
> static anotherclass obj;
> }
>
> No i do the initialization in the same header file:
> anotherclass myclass::obj;

It's known in some places as a "definition".

> If I include this header in one cpp of another project, everything works
> fine, but if the projects has more than one cpp
> file, that includes the header, I get the linker error, that there are
> duplicated calls for the myclass::obj part.

Headers are inconsequential, they are not compiled.  Translation units 
are compiled.  If you have your *definition* in more than one 
translation unit (by means of including the same definition code in more 
than one translation unit), you have what is known as "multiple 
definition" of that symbol (object), and that's prohibited in C++.

> I can create a cpp file with the initialization, but is there a
> "header-only" solution to do the initialization without
> linker problems eg a design pattern or anything else?

Yes: don't include it in more than one translation unit.

 > My goal the static
> members should be initialize within
> their header file and the header files can be include more than once.

That's not achievable in C++.

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#10804

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2011-10-11 17:24 +0200
Message-ID<j71n4g$45t$1@dont-email.me>
In reply to#10798
On 11.10.2011 15:45, Victor Bazarov wrote:
> On 10/11/2011 8:53 AM, Philipp Kraus wrote:
>> I have written a header-only class with inline calls like in a header
>> file only like:
>>
>> --header.hpp---
>> class myclass {
>>
>> public :
>>
>> private :
>> static anotherclass obj;
>> }
>>
[snippety!]

>  > My goal the static
>> members should be initialize within
>> their header file and the header files can be include more than once.
>
> That's not achievable in C++.

Oh, it's easy.

E.g.

     template< class Dummy_ >
     struct myclass_statics
     {
         static anotherclass obj;
     };

     template< class Dummy_ >
     anotherclass myclass_statics<Dummy_>::obj;


     class myclass
         : private myclass_statics<void>
     {
     public:
         // blah blah
     };

It's just very verbose, since C++ doesn't have a clean "inline" keyword.


Cheers & hth.,

- Alf

[toc] | [prev] | [next] | [standalone]


#10805

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2011-10-11 17:26 +0200
Message-ID<j71n7j$45t$2@dont-email.me>
In reply to#10794
On 11.10.2011 14:53, Philipp Kraus wrote:
> Hello,
>
> I have written a header-only class with inline calls like in a header
> file only like:
>
> --header.hpp---
> class myclass {
>
>     public :
>
>     private :
>          static anotherclass obj;
> };

Instead do like

   class myclass
   {
   public:
       // whaver
   private:
       static anotherclass& obj()
       {
           static anotherclass theObj;
           return theObj;
       }
   };

Cheers & hth.,

- Alf

[toc] | [prev] | [next] | [standalone]


#10806

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-10-11 12:17 -0400
Message-ID<j71q6b$pmg$1@dont-email.me>
In reply to#10805
On 10/11/2011 11:26 AM, Alf P. Steinbach wrote:
> On 11.10.2011 14:53, Philipp Kraus wrote:
>> Hello,
>>
>> I have written a header-only class with inline calls like in a header
>> file only like:
>>
>> --header.hpp---
>> class myclass {
>>
>> public :
>>
>> private :
>> static anotherclass obj;
>> };
>
> Instead do like
>
> class myclass
> {
> public:
> // whaver
> private:
> static anotherclass& obj()
> {
> static anotherclass theObj;
> return theObj;
> }
> };
>

That will introduce "extraneous" parentheses after the name of the 
"object" (although it is only used in the class itself, so it's not such 
a big deal, of course).  The template solution (that you have posted in 
response to my "no possible" claim) is a neat trick, but requires a 
template definition for every class with a static obj.  It can be 
wrapped in a bunch of macros, and made "cleaner" and "less verbose" (so 
to speak), OTOH, why verbosity never scared the existing compilers, 
right?  Most of the C++ Standard Library is very verbose...

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#10807

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-10-11 17:29 +0100
Message-ID<-eqdneSnaMKU8gnTnZ2dnUVZ8t6dnZ2d@giganews.com>
In reply to#10806
On 11/10/2011 17:17, Victor Bazarov wrote:
> On 10/11/2011 11:26 AM, Alf P. Steinbach wrote:
>> On 11.10.2011 14:53, Philipp Kraus wrote:
>>> Hello,
>>>
>>> I have written a header-only class with inline calls like in a header
>>> file only like:
>>>
>>> --header.hpp---
>>> class myclass {
>>>
>>> public :
>>>
>>> private :
>>> static anotherclass obj;
>>> };
>>
>> Instead do like
>>
>> class myclass
>> {
>> public:
>> // whaver
>> private:
>> static anotherclass& obj()
>> {
>> static anotherclass theObj;
>> return theObj;
>> }
>> };
>>
>
> That will introduce "extraneous" parentheses after the name of the
> "object" (although it is only used in the class itself, so it's not such
> a big deal, of course). The template solution (that you have posted in
> response to my "no possible" claim) is a neat trick, but requires a
> template definition for every class with a static obj. It can be wrapped
> in a bunch of macros, and made "cleaner" and "less verbose" (so to
> speak), OTOH, why verbosity never scared the existing compilers, right?
> Most of the C++ Standard Library is very verbose...

One should be keeping such static objects to a minimum as they are no 
better than global variables/objects; Alf's Meyers Singleton is an 
improvement on globals as the construction order is defined unlike 
different class static objects in different TUs.

Complaining about "extraneous" parentheses is plain silly.

/Leigh

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web