[Boost.Test 1.34] Multiple instances of unit_test_log_t singleton
Hi, All! I am using Boost.Test library in my own application and I have included boost/test/unit_test.hpp in many my cpp-files. When I used boost version 1.33.1 all works fine. But in version 1.34 I have following compiler error: file1.obj : error LNK2005: "class unit_test_log_t::boost::unit_test_log_t & boost::unit_test::`anonymous namespace'::unit_test_log" (?unit_test_log@?A0xa35d3712@unit_test@boost@@3AAVunit_test_log_t@23@A) already defined in file2.obj After including boost/test/unit_test.hpp class unit_test_log has multiple instances. See boost/test/unit_test_log.hpp for details: BOOST_TEST_SINGLETON_INST( unit_test_log ) It means that following code will be included in many cpp-files! namespace { unit_test_log_t & inst = unit_test_log_t::instance(); } When I replace BOOST_TEST_SINGLETON_INST( unit_test_log ) in boost/test/unit_test_log.hpp with namespace {extern unit_test_log_t & unit_test_log;} and in one of my cpp-files add: namespace boost { namespace unit_test { BOOST_TEST_SINGLETON_INST( unit_test_log ) } } all works fine May be I do not understand something? Is there any legal workaround from this situation? I do not like touch boost core files by myself. Thank you! VC++ 7.1, boost 1.34, xp sp2.
"Kolya"
wrote in message news:1f5259800705230242hb812523mc864b34c6d35e145@mail.gmail.com... Hi, All! I am using Boost.Test library in my own application and I have included boost/test/unit_test.hpp in many my cpp-files. When I used boost version 1.33.1 all works fine. But in version 1.34 I have following compiler error:
file1.obj : error LNK2005: "class unit_test_log_t::boost::unit_test_log_t & boost::unit_test::`anonymous namespace'::unit_test_log" (?unit_test_log@? A0xa35d3712@unit_test@boost@@3AAVunit_test_log_t@23 @A) already defined in file2.obj
Looks liek clear compiler bug. Anounimus namespace is used specifically to avoid duplicate symbols.
After including boost/test/unit_test.hpp class unit_test_log has multiple instances. See boost/test/unit_test_log.hpp for details:
BOOST_TEST_SINGLETON_INST( unit_test_log )
It means that following code will be included in many cpp-files!
namespace { unit_test_log_t & inst = unit_test_log_t::instance(); }
Try adding static. Though it's like saying the same twice. namespace { static unit_test_log_t & inst = unit_test_log_t::instance(); } HTH, Gennadiy
Gennadiy Rozental wrote:
"Kolya"
wrote in message news:1f5259800705230242hb812523mc864b34c6d35e145@mail.gmail.com... Hi, All! I am using Boost.Test library in my own application and I have included boost/test/unit_test.hpp in many my cpp-files. When I used boost version 1.33.1 all works fine. But in version 1.34 I have following compiler error:
file1.obj : error LNK2005: "class unit_test_log_t::boost::unit_test_log_t & boost::unit_test::`anonymous namespace'::unit_test_log" (?unit_test_log@? A0xa35d3712@unit_test@boost@@3AAVunit_test_log_t@23 @A) already defined in file2.obj
Looks liek clear compiler bug. Anounimus namespace is used specifically to avoid duplicate symbols.
It's very common for compilers to become confused when an anonymous namespace resides in a precompiled header.
"Peter Dimov"
Gennadiy Rozental wrote:
"Kolya"
wrote in message news:1f5259800705230242hb812523mc864b34c6d35e145@mail.gmail.com... Hi, All! I am using Boost.Test library in my own application and I have included boost/test/unit_test.hpp in many my cpp-files. When I used boost version 1.33.1 all works fine. But in version 1.34 I have following compiler error:
file1.obj : error LNK2005: "class unit_test_log_t::boost::unit_test_log_t & boost::unit_test::`anonymous namespace'::unit_test_log" (?unit_test_log@? A0xa35d3712@unit_test@boost@@3AAVunit_test_log_t@23 @A) already defined in file2.obj
Looks liek clear compiler bug. Anounimus namespace is used specifically to avoid duplicate symbols.
It's very common for compilers to become confused when an anonymous namespace resides in a precompiled header.
Well. Don't put Boost.Test header in precompiled headers set, if you know the issue. unit_test_hpp shouldn't slow down compilation. Gennadiy
This bug exists at msvc-6.0 and msvc-7.1 when precompiled headers is
used. It is *not* exits at msvc-8.0 at all. I have no msvc-7.0 so I
suppose it behavior is similar to msvc-7.1.
Also I have following linker error at msvc-6.0 when I have solved
previous problem:
filemain.obj : error LNK2005: "bool boost::test_tools::`anonymous
namespace'::dummy_cond"
(?dummy_cond@?%..\..\boost/test/unit_test_log.hpp1238016409@test_tools@boost@@3_NA)
already defined in pch.obj
This patches should fix both problems:
==========
--- boost/boost/test/utils/trivial_singleton.hpp 2006-01-01
19:29:38.000000000 +0200
+++ boost/boost/test/utils/trivial_singleton.hpp.patched 2007-05-27
20:00:15.031250000 +0300
@@ -55,6 +55,10 @@
#define BOOST_TEST_SINGLETON_INST( inst ) \
static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();
+#elif BOOST_WORKAROUND(BOOST_MSVC, < 1400)
+#define BOOST_TEST_SINGLETON_INST( inst ) \
+namespace { static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst,
_t)::instance(); }
+
#else
#define BOOST_TEST_SINGLETON_INST( inst ) \
==========
--- boost/boost/test/test_tools.hpp.orig.bak 2007-02-22
19:57:30.000000000 +0200
+++ boost/boost/test/test_tools.hpp 2007-05-27 18:53:26.718750000 +0300
@@ -259,8 +259,16 @@
typedef unit_test::const_string const_string;
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+
+static dummy_cond = false;
+
+#else
+
namespace { bool dummy_cond = false; }
+#endif
+
namespace tt_detail {
//
**************************************************************************
//
==========
Following command line options and files I have used to write and test
patches.
bjam --toolset=msvc-6.0 --without-python debug threading=multi
link=static runtime-link=shared
bjam --toolset=msvc-7.1 --without-python debug threading=multi
link=static runtime-link=shared
bjam --toolset=msvc-8.0 --without-python debug threading=multi
link=static runtime-link=shared
==========
# Jamfile.v2
cpp-pch pch : stdafx.h ;
exe filemain : filemain.cpp file1.cpp stdafx.cpp pch ;
==========
// stdafx.h
#ifndef STDAFX_H
#define STDAFX_H
#include
"Kolya"
wrote in message news:1f5259800705230242hb812523mc864b34c6d35e145@mail.gmail.com... Hi, All! I am using Boost.Test library in my own application and I have included boost/test/unit_test.hpp in many my cpp-files. When I used boost version 1.33.1 all works fine. But in version 1.34 I have following compiler error:
file1.obj : error LNK2005: "class unit_test_log_t::boost::unit_test_log_t & boost::unit_test::`anonymous namespace'::unit_test_log" (?unit_test_log@? A0xa35d3712@unit_test@boost@@3AAVunit_test_log_t@23 @A) already defined in file2.obj
Looks liek clear compiler bug. Anounimus namespace is used specifically to avoid duplicate symbols.
After including boost/test/unit_test.hpp class unit_test_log has multiple instances. See boost/test/unit_test_log.hpp for details:
BOOST_TEST_SINGLETON_INST( unit_test_log )
It means that following code will be included in many cpp-files!
namespace { unit_test_log_t & inst = unit_test_log_t::instance(); }
Try adding static. Though it's like saying the same twice.
namespace { static unit_test_log_t & inst = unit_test_log_t::instance(); }
"Kolya Kosenko"
wrote in message news:4659BEE9.9040907@gmail.com... This bug exists at msvc-6.0 and msvc-7.1 when precompiled headers is used. It is *not* exits at msvc-8.0 at all. I have no msvc-7.0 so I suppose it behavior is similar to msvc-7.1. Also I have following linker error at msvc-6.0 when I have solved previous problem: filemain.obj : error LNK2005: "bool boost::test_tools::`anonymous namespace'::dummy_cond" (?dummy_cond@? %..\..\boost/test/unit_test_log.hpp1238016409@test_tools@boost@@3_NA) already defined in pch.obj
This patches should fix both problems: ========== --- boost/boost/test/utils/trivial_singleton.hpp 2006-01-01 19:29:38.000000000 +0200 +++ boost/boost/test/utils/trivial_singleton.hpp.patched 2007-05-27 20:00:15.031250000 +0300 @@ -55,6 +55,10 @@ #define BOOST_TEST_SINGLETON_INST( inst ) \ static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();
+#elif BOOST_WORKAROUND(BOOST_MSVC, < 1400) +#define BOOST_TEST_SINGLETON_INST( inst ) \ +namespace { static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
Do we really need anonymous namespace for this case?
+ #else
#define BOOST_TEST_SINGLETON_INST( inst ) \ ========== --- boost/boost/test/test_tools.hpp.orig.bak 2007-02-22 19:57:30.000000000 +0200 +++ boost/boost/test/test_tools.hpp 2007-05-27 18:53:26.718750000 +0300 @@ -259,8 +259,16 @@
typedef unit_test::const_string const_string;
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
I do not plan to include msvc 6.0 targeted patches, unless boost regression testing is affected.
I think it would be nice to include tests for precompiled headers in regression tests of Boost.Test library.
Every compiler means something different by this term. You can't write portable code with precompiled headers. Gennadiy
Gennadiy Rozental wrote:
--- boost/boost/test/utils/trivial_singleton.hpp 2006-01-01 19:29:38.000000000 +0200 +++ boost/boost/test/utils/trivial_singleton.hpp.patched 2007-05-27 20:00:15.031250000 +0300 @@ -55,6 +55,10 @@ #define BOOST_TEST_SINGLETON_INST( inst ) \ static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();
+#elif BOOST_WORKAROUND(BOOST_MSVC, < 1400) +#define BOOST_TEST_SINGLETON_INST( inst ) \ +namespace { static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
Do we really need anonymous namespace for this case?
No, anonymous namespace is not required in this case.
Every compiler means something different by this term. You can't write portable code with precompiled headers. If you write a portable code, you can use macro |BOOST_BUILD_PCH_ENABLED for divide compilers that supports precompiled headers from compilers than does not support it.
|It is need to support only for precompiled headers which is supported by boost build system - msvc and gcc only. Boost.Build officially supports precompiled headers: http://www.boost.org/doc/html/bbv2/tasks.html#bbv2.reference.precompiled_hea... Thank you. Kolya Kosenko
participants (4)
-
Gennadiy Rozental
-
Kolya
-
Kolya Kosenko
-
Peter Dimov