[ptr_container] trunk has problems with multiple definitions of xml_names with multiple TUs

This gives multiple definition errors when #include'd by more than one translation unit. namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Regards, -- Felipe Magno de Almeida

Felipe Magno de Almeida skrev:
This gives multiple definition errors when #include'd by more than one translation unit.
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } }
Thanks. Is there an easy way to fix it? -Thorsten

----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Thorsten Ottosen Sent: 07 November 2007 12:02 To: boost@lists.boost.org Subject: Re: [boost] [ptr_container] trunk has problems with multiple definitions of xml_names with multiple TUs
Felipe Magno de Almeida skrev:
This gives multiple definition errors when #include'd by more than one translation unit.
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } }
Thanks. Is there an easy way to fix it?
-Thorsten
One option would be: namespace ptr_container_detail { const char* count() { return "count"; } etc. -- Martin Bonner Senior Software Engineer/Team Leader PI SHURLOK LTD Telephone: +44 1223 441434 / 203894 (direct) Fax: +44 1223 203999 Email: martin.bonner@pi-shurlok.com www.pi-shurlok.com disclaimer

Martin Bonner skrev:
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
-Thorsten
One option would be: namespace ptr_container_detail { const char* count() { return "count"; }
with an "inline" in front of each function, I presume? -Thorsten

Thorsten Ottosen wrote:
Martin Bonner skrev:
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
-Thorsten
One option would be: namespace ptr_container_detail { const char* count() { return "count"; }
with an "inline" in front of each function, I presume?
Oops! I missed that they are namespace level rather than class members. Yes, an "inline" would improve things markedly. -- Martin Bonner Senior Software Engineer/Team Leader PI SHURLOK LTD Telephone: +44 1223 441434 / 203894 (direct) Fax: +44 1223 203999 Email: martin.bonner@pi-shurlok.com www.pi-shurlok.com disclaimer

Martin Bonner wrote:
Thorsten Ottosen wrote:
Martin Bonner skrev:
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
-Thorsten One option would be: namespace ptr_container_detail { const char* count() { return "count"; } with an "inline" in front of each function, I presume?
Oops! I missed that they are namespace level rather than class members.
Yes, an "inline" would improve things markedly.
Err don't you just need to make them const so that they have internal linkage? i.e. namespace boost { namespace ptr_container_detail { const char* const count = "count"; const char* const item = "item"; const char* const first = "first"; const char* const second = "second"; } } Thanks, Michael Marcin

This can cause warnings on various gcc versions, if the header file is included in a translation unit in which those constants are not used. The inline function, instead, will cause no problem. Corrado On Nov 7, 2007 9:14 PM, Michael Marcin <mmarcin@method-solutions.com> wrote:
Martin Bonner wrote:
Thorsten Ottosen wrote:
Martin Bonner skrev:
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
-Thorsten One option would be: namespace ptr_container_detail { const char* count() { return "count"; } with an "inline" in front of each function, I presume?
Oops! I missed that they are namespace level rather than class members.
Yes, an "inline" would improve things markedly.
Err don't you just need to make them const so that they have internal linkage?
i.e.
namespace boost { namespace ptr_container_detail { const char* const count = "count"; const char* const item = "item"; const char* const first = "first"; const char* const second = "second"; } }
Thanks,
Michael Marcin
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- __________________________________________________________________________ dott. Corrado Zoccolo mailto:zoccolo@di.unipi.it PhD - Department of Computer Science - University of Pisa, Italy --------------------------------------------------------------------------

Corrado Zoccolo wrote:
This can cause warnings on various gcc versions, if the header file is included in a translation unit in which those constants are not used. The inline function, instead, will cause no problem.
Sigh.. I'm reminded of http://www.ddj.com/blog/cppblog/archives/2007/10/the_hazards_of.html Is portable C++ an oxymoron? Oh well completely off topic. Thanks, Michael Marcin

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Michael Marcin Sent: 07 November 2007 20:21 To: boost@lists.boost.org Subject: Re: [boost] [ptr_container] trunk has problems with multiple definitions of xml_names with multiple TUs
Sigh.. I'm reminded of http://www.ddj.com/blog/cppblog/archives/2007/10/the_hazards_of.html
Is portable C++ an oxymoron?
Oh well completely off topic.
Not at all. It's a continuing problem, but I think the 'solution' is to suppress warnings in a way that *documents* saying: "Yes, we know, you would get a warning from this, but someone who ought to know (author etc) has decided that it isn't a helpful warning - so you won't". Sadly, there isn't a portable way of doing this (something Standards people should be apologising for), so for Boost it's a load of hassle. But it's most off-putting to get a zillion lines of warnings when you compile a simple bit of Boost - you certainly don't get a chance to find warnings that apply to your own code, never mind the errors. So I think we should continue to put effort into reducing the risk that Boost code causes spurious warnings. Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

On Nov 7, 2007 9:18 PM, Corrado Zoccolo <czoccolo@gmail.com> wrote:
This can cause warnings on various gcc versions, if the header file is included in a translation unit in which those constants are not used. The inline function, instead, will cause no problem.
Corrado
A gcc problem may be solved with a gcc workaround. Won't __attribute__((unused)) solve the problem? Or maybe a dummy inline function that "uses" 'em? -- gpd

AMDG Michael Marcin <mmarcin <at> method-solutions.com> writes:
namespace boost { namespace ptr_container_detail { const char* const count = "count"; const char* const item = "item"; const char* const first = "first"; const char* const second = "second"; } }
Alas, that only replace one form of ODR violation with more subtle one. static const char* count = "count"; void foo(const char*); inline void bar() { // ODR violation here. count refers to // different objects in different translation // units. (See section 3.2/5 of the standard.) foo(count); } In Christ, Steven Watanabe

on Wed Nov 07 2007, Steven Watanabe <steven-AT-providere-consulting.com> wrote:
AMDG
Michael Marcin <mmarcin <at> method-solutions.com> writes:
namespace boost { namespace ptr_container_detail { const char* const count = "count"; const char* const item = "item"; const char* const first = "first"; const char* const second = "second"; } }
Alas, that only replace one form of ODR violation with more subtle one.
static const char* count = "count";
void foo(const char*); inline void bar() { // ODR violation here. count refers to // different objects in different translation // units. (See section 3.2/5 of the standard.) foo(count); }
template <int = 0> struct count { static char const* const s; }; template <int n> char const* const count<n>::s = "count"; inline void bar() { foo(count<>::s); } HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Steven Watanabe skrev:
Alas, that only replace one form of ODR violation with more subtle one.
static const char* count = "count";
void foo(const char*); inline void bar() { // ODR violation here. count refers to // different objects in different translation // units. (See section 3.2/5 of the standard.) foo(count); }
In Christ,
Ok, but the inline function approach does not have this problem, right? -Thorsten

On 11/7/07, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Felipe Magno de Almeida skrev:
This gives multiple definition errors when #include'd by more than one translation unit.
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } }
Thanks. Is there an easy way to fix it?
I couldn't think of anything that wouldn't cause ODR violation.
-Thorsten
-- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
On 11/7/07, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Felipe Magno de Almeida skrev:
This gives multiple definition errors when #include'd by more than one translation unit.
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
I couldn't think of anything that wouldn't cause ODR violation.
It's a bit ugly, but you can use templates. There's an example in boost/date_time/time_facet.hpp, but it goes something like this: template <class CharT> struct ptr_container_stuff { public: typedef CharT char_type; static const char_type count[6]; static const char_type item[5]; ... }; template <class CharT> const typename ptr_container_stuff<CharT>::char_type ptr_container_stuff<CharT>::count[6] = {'f','i','r','s','t'}; template <class CharT> const typename ptr_container_stuff<CharT>::char_type ptr_container_stuff<CharT>::item[5] = {'i','t','e','m'}; Jeff

Felipe Magno de Almeida wrote:
On 11/7/07, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Felipe Magno de Almeida skrev:
This gives multiple definition errors when #include'd by more than one translation unit.
namespace boost { namespace ptr_container_detail { const char* count = "count"; const char* item = "item"; const char* first = "first"; const char* second = "second"; } } Thanks. Is there an easy way to fix it?
I couldn't think of anything that wouldn't cause ODR violation.
-Thorsten
Can't you just change it to const char* const count = "count"; etc? -Lewis
participants (11)
-
Corrado Zoccolo
-
David Abrahams
-
Felipe Magno de Almeida
-
Giovanni Piero Deretta
-
Jeff Garland
-
Lewis Hyatt
-
Martin Bonner
-
Michael Marcin
-
Paul A Bristow
-
Steven Watanabe
-
Thorsten Ottosen