Opened 11 years ago

Closed 11 years ago

Last modified 10 years ago

#5615 closed Feature Requests (wontfix)

BOOST_CHECK_EQUAL does not work well with const static members

Reported by: anonymous Owned by: Gennadiy Rozental
Milestone: To Be Determined Component: test
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc:

Description

I have tried to create set of test cases using BOOST_AUTO_TEST_CASE_TEMPLATE() macro. Each tested class shares the same interface, but values returned from functions are different. Therefore I decided to use helper traits template to avoid code duplication. Each traits struct contains arguments and expected results for tested classes, stored as static const values - see example below. Unfortunately this code does not link successfully - linker complains about missing static struct members. Fortunately workaround is simple - just copy expected value to temporary variable and use it in BOOST_CHECK_EQUAL().

Please fix this to allow this code to compile and link successfully, without using workaround.

class SomeClass
{
public:
    int test(int arg)
    {
        return arg + 1;
    }
};

BOOST_AUTO_TEST_SUITE( Test_err )

    template<typename TClass>
    struct Tested_class_traits;
    
    template<>
    struct Tested_class_traits<SomeClass>
    {
        static const int arg = 1;
        static const int result = 2;
    };
    
    typedef boost::mpl::list<
        SomeClass
    > Tested_types;
    
    BOOST_AUTO_TEST_CASE_TEMPLATE( Test_err_test, TClass, Tested_types )
    {
        typedef Tested_class_traits<TClass> TestTraits;
        
        TClass obj;
        BOOST_CHECK_EQUAL( obj.test(TestTraits::arg), TestTraits::result );
    }
    
BOOST_AUTO_TEST_SUITE_END()

Change History (3)

comment:1 by anonymous, 11 years ago

Here is the linker error:

/path/to/Test_err.cc:34: undefined reference to `Test_err::Tested_class_traits<SomeClass>::result'

comment:2 by Steven Watanabe, 11 years ago

Resolution: wontfix
Status: newclosed

This is not unique to Boost.Test. An out of line definition of a static constant is required in some circumstances. You can often get away without it, but it's safest just to provide it all the time.

in reply to:  2 comment:3 by anonymous, 10 years ago

Replying to steven_watanabe:

This is not unique to Boost.Test. An out of line definition of a static constant is required in some circumstances. You can often get away without it, but it's safest just to provide it all the time.

Hi, I've just tried two very similar test cases:

#define BOOST_TEST_MODULE geez
#include <boost/test/unit_test.hpp>
#include <boost/tuple/tuple.hpp>
BOOST_AUTO_TEST_SUITE(foo)
BOOST_AUTO_TEST_CASE(bar)
{
  using boost::tuples::length;
  using boost::tuples::tuple;
  BOOST_CHECK_EQUAL( (length<tuple<int, char> >::value), 2);
}
BOOST_AUTO_TEST_SUITE_END()

this program won't link:

ptomulik@barakus:$ g++ -DBOOST_TEST_DYN_LINK=1 -ansi -Werror -Wall -Wextra -pedantic b.cpp -lboost_unit_test_framework
/tmp/cc1snUGj.o: In function `foo::bar::test_method()':
b.cpp:(.text+0x188): undefined reference to `boost::tuples::length<boost::tuples::tuple<int, char, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >::value'
collect2: error: ld returned 1 exit status

Quite suprising, but when I replace BOOST_CHECK_EQUAL(a,b) with BOOST_CHECK(a == b), the program compiles and links smoothly:

#define BOOST_TEST_MODULE geez
#include <boost/test/unit_test.hpp>
#include <boost/tuple/tuple.hpp>
BOOST_AUTO_TEST_SUITE(foo)
BOOST_AUTO_TEST_CASE(bar)
{
  using boost::tuples::length;
  using boost::tuples::tuple;
  BOOST_CHECK( (length<tuple<int, char> >::value) == 2);
}                 
BOOST_AUTO_TEST_SUITE_END()
ptomulik@barakus:$ g++ -DBOOST_TEST_DYN_LINK=1 -ansi -Werror -Wall -Wextra -pedantic b.cpp -lboost_unit_test_framework
ptomulik@barakus:$

This is quite strange, and looks like bug in boost test framework, boost tuple implementation or elsewhere.

Note, that very similar code with BOOST_CHECK_EQUAL but for std::tuple compiles and links just fine:

#define BOOST_TEST_MODULE geez
#include <boost/test/unit_test.hpp>
#include <tuple>
BOOST_AUTO_TEST_SUITE(foo)
BOOST_AUTO_TEST_CASE(bar)
{
  using std::tuple_size;
  using std::tuple;
  BOOST_CHECK_EQUAL( (tuple_size<tuple<int, char> >::value), 2);
}                 
BOOST_AUTO_TEST_SUITE_END()
ptomulik@barakus:$ g++ -DBOOST_TEST_DYN_LINK=1 -ansi -std=c++11 -Werror -Wall -Wextra -pedantic b.cpp -lboost_unit_test_framework
ptomulik@barakus:$

Note: See TracTickets for help on using tickets.