[BOOST]BOOST_AUTO_TEST_CASE_TEMPLATE vs BOOST_AUTO_TEST_CASE
Hi, Scenario1: Both files are present in the same Project BoostUnitTest. fileA: typedef boost::mpl::list<long long,unsigned char> test_types; BOOST_AUTO_TEST_SUITE(MySuite) BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types ) { BOOST_CHECK_EQUAL( sizeof(T), (unsigned)4 ); } BOOST_AUTO_TEST_SUITE_END() fileB: typedef boost::mpl::list<long long,unsigned char> test_types; BOOST_AUTO_TEST_SUITE(MySuite) BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types ) { BOOST_CHECK_EQUAL( sizeof(T), (unsigned)4 ); } BOOST_AUTO_TEST_SUITE_END() As shown above, MySuite is extended across 2 files fileA and fileB. The BOOST_AUTO_TEST_CASE_TEMPLATE name is same across the both the files and and the suite name is also same across both the files.. Boost is able to differentiate between the 2 test cases and the test cases are executed. Scenario2: fileA: BOOST_AUTO_TEST_SUITE(MySuite) BOOST_AUTO_TEST_CASE( my_test) { BOOST_CHECK_EQUAL(1,1); } BOOST_AUTO_TEST_SUITE_END() fileB: BOOST_AUTO_TEST_SUITE(MySuite) BOOST_AUTO_TEST_CASE_TEMPLATE( my_test ) { BOOST_CHECK_EQUAL( 1,1 ); } BOOST_AUTO_TEST_SUITE_END() In the scenario2, I get a compile time error (Error 1 error LNK2005: "public: void __thiscall mySuite::insuite2::test_method(void)" (?test_method@insuite2@mySuite@@QAEXXZ) already defined in BoostUnitTest.obj) which basically suggests that one or more multiply defined symbols are found. Why is the behaviour different in these 2 scenarios? How is Boost able to differenciate between the 2 test cases in Scenario1? Mit freundlichen Grüßen / Best Regards, Hemanth Choudary MV RBEI/ETA1
[Please do not mail me a copy of your followup] boost-users@lists.boost.org spake the secret code <518813FAAE539546847B8F61C0C9B2FA9B7B2388@SGPMBX06.APAC.bosch.com> thusly:
Why is the behaviour different in these 2 scenarios? How is Boost able to differenciate between the 2 test cases in Scenario1?
The difference is that non-template test cases are generated statically with unique names that cannot violate the one-definition rule. When you use BOOST_AUTO_TEST_CASE in multiple translation units inside the same test suite (which is really just a glorified namespace), the test cases must have unique names in order to not violate the one definition rule. When you use BOOST_AUTO_TEST_CASE_TEMPLATE, you get a uniquely named static instance of a class whose constructor registers the dynamically generated test cases for each of the template arguments. The same templatized code appears in each translation unit, but C++ allows the linker to discard all but one of the multiple instantiations of the same template. In order to provide this explanation, what I did was to take your template example code and expand the BOOST_AUTO_TEST_CASE_TEMPLATE macro until it was resolved down into actual code. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Hemanth Choudary M V (RBEI/ETA1 <HemanthChoudary.MV <at> in.bosch.com> writes:
Why is the behaviour different in these 2 scenarios? How is Boost able to differenciate between the 2 test cases in Scenario1?
I think what it essentially comes to is this: If you have in header H: class A{ public: void test_method(); } void A::test_method() {} // note NO inline and include this header in 2 C++ files A and B linker will complain. If on the other hand you have this in H: template<typename Foo> class A{ public: void test_method(); } template<typename Foo> void A<Foo>::test_method() {} // inline implied Linker is required to merge multiple definitions from different translation units and program builds fine. These are rules of C++. HTH, Gennadiy
participants (3)
-
Gennadiy Rozental
-
Hemanth Choudary M V (RBEI/ETA1)
-
legalize+jeeves@mail.xmission.com