The documentation for pool in 1.53.0 claims that it is 'header-only'. However, a minimal program:
#include <boost/pool/pool_alloc.hpp>
int main() {
return 0;
}
ends up with undefined symbols from boost_system, and bcp thinks that boost_system is required. Is there #define or something to cure this?
This is a known bug. https://svn.boost.org/trac/boost/ticket/7085.
If you don't need multi-threading, we could
modify pool/detail/mutex.hpp to not to include <boost/thread/mutex.hpp> as described in the URL,
...
#if defined(BOOST_HAS_THREADS) && !defined(BOOST_NO_MT) && !defined(BOOST_POOL_NO_MT)
#include <boost/thread/mutex.hpp>
#endif
...
or, if you can't modify the files, fake the compiler that <boost/thread/mutex.hpp> has been defined:
#define BOOST_POOL_NO_MT // disable multi-threading
#define BOOST_THREAD_MUTEX_HPP // define the #include-guard to disable the header
#include <boost/pool/pool_alloc.hpp>
int main () {}
or, if you do need multi-threading, but C++11 is allowed, we could use std::mutex to substitute boost::mutex:
#define BOOST_THREAD_MUTEX_HPP
#include <mutex>
namespace boost {
using std::mutex;
}
#include <boost/pool/pool_alloc.hpp>
int main () {}
Related
When I use CLion on a Mac to compile C++ code for highlight removal in a single image, there is an error:
Please help me fix it.
#ifndef QX_CVPR09_CTBF_BASIC_H
#define QX_CVPR09_CTBF_BASIC_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <numeric>
#include <vector>
#include <process.h>
#include <direct.h>
#include <io.h>
#include <time.h>
#include <string>
#include <memory.h>
#include <algorithm>
#include <functional> // For greater<int>()
#include <iostream>
#if _MSC_VER > 1020 // if VC++ version is > 4.2
using namespace std; // std c++ libs implemented in std
#endif
#define QX_DEF_PADDING 10
#define QX_DEF_THRESHOLD_ZERO 1e-6
class qx_timer {public: void start(); float stop(); void time_display(char *disp=""); void fps_display(char *disp=""); private: clock_t m_begin; clock_t m_end;};
It's a part of my code. The full code is too long.
process.h
process.h is a C header file which contains function declarations and
macros used in working with threads and processes. Most C compilers
that target DOS, Windows 3.1x, Win32, OS/2, Novell NetWare or DOS
extenders supply this header and the library functions in their C
library. Neither the header file nor most of the functions are defined
by either the ANSI/ISO C standard or by POSIX.
Depends on which platform you compile and what standard you use. If you are on linux or compile with c99/ansi standard then this header will probably just not be available (which might be your error)
Below is a minimal example to use the great Boost.Serialization library.
To compile the library I need to link with the boost_serialization precompiled library.
$ c++ -std=c++11 example.cpp -o example.x -lboost_serialization
^^^^^^^^^^^^^^^^^^^^^
The library is heavily templated an although complicated internally the actual code (function body) is quite simple. There are only a few references that need the linking, namely:
boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::text_oarchive_impl(std::ostream&, unsigned int)
boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::text_iarchive_impl(std::istream&, unsigned int)
boost::archive::text_iarchive_impl<boost::archive::text_oarchive>::~text_oarchive_impl()
boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::~text_iarchive_impl()
...
boost::archive::archive_exception::~archive_exception()'
Is there a chance that the library can be used without linking as a header-only library?
For example some undocumented trick or hack?
That would make it more simple to use in some supercomputer clusters and environments where it is not that simply to compile Boost.
#include<sstream>
#include<numeric>
#include<boost/archive/text_oarchive.hpp> // needs linking
#include<boost/archive/text_iarchive.hpp>
#include<boost/serialization/vector.hpp>
int main(){
std::vector<double> v(10); std::iota(v.begin(), v.end(), 0);
std::stringstream ss;
{
boost::archive::text_oarchive toa(ss);
toa << v;
}
std::vector<double> v2;
boost::archive::text_iarchive tia(ss);
tia >> v2;
assert(v == v2);
}
EDIT: I would be very cool if the library gave the option to be header only, like Boost.Asio does (https://stackoverflow.com/a/40729439/225186.)
EDIT2: The author and maintainer of Boost.Serialization rejected the idea of making it header only. https://github.com/boostorg/serialization/issues/71
I ended up including the cpp sources from a certain version of Boost Serialization.
I chose the cpp files by trial and error.
https://gitlab.com/correaa/boost-mpi3/-/tree/master/include/mpi3/serialization_hack
Basically, I include these cpp files from the same place I would include the Serialization hpp files.
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_streambuf_locale_saver.hpp>
#include <boost/archive/detail/auto_link_archive.hpp>
//#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
#include <boost/serialization/array.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/item_version_type.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpl/placeholders.hpp>
#include <any>
#include <optional>
// use this to avoid need for linking -lserialization
#ifdef _MAKE_BOOST_SERIALIZATION_HEADER_ONLY
//#include <boost/archive/detail/decl.hpp>
#if BOOST_VERSION > 106000 && BOOST_VERSION < 106600
#include "../mpi3/serialization_hack/singleton.cpp"
#endif
#if BOOST_VERSION < 105900
#define BOOST_ARCHIVE_DECL
#define BOOST_SERIALIZATION_DECL
#endif
// NOLINTBEGIN(hicpp-use-auto,modernize-use-auto) external code
#include "../mpi3/serialization_hack/archive_exception.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/basic_archive.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/basic_iarchive.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/basic_iserializer.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/basic_oarchive.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/basic_oserializer.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/extended_type_info.cpp" // NOLINT(bugprone-suspicious-include) hack
#include "../mpi3/serialization_hack/extended_type_info_typeid.cpp" // NOLINT(bugprone-suspicious-include) hack
// NOLINTEND(hicpp-use-auto,modernize-use-auto)
A problem with this approach is that I had to modify the sources to accommodate different versions of Boost.Serialization and also had to do some modification to appease compiler warnings and static analyzers.
I've been creating codes using C++ STL. And I want to use "queue".
So, I wrote the codes like below.
But, I encountered "queue is not a template" error.
As you can see, I wrote headers related with queue (iostream, queue) in "Common.h" file and wrote include "Common.h" in "DataQueue.h" file. But, VS2013 IDE tool said that 'queue m_deQueue' is error because queue is not a template. I don't know why.. this error occured. Any help is appreciated!
//[Common.h]
#ifndef _COMMON_
#define _COMMON_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
//thread related headers
#include <Windows.h>
#include <process.h>
//socket related headers
#include <winsock.h>
#include <iostream>
#include <queue>
#include <deque>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
#endif
//[DataQueue.h]
#ifndef _QUEUE_
#define _QUEUE_
#include "SocketStruct.h"
#include "Common.h"
class CDataQueue{
private:
static CDataQueue* m_cQueue;
// deque <ST_MONITORING_RESULT> m_deQueue;
queue <ST_MONITORING_RESULT> m_deQueue;
CRITICAL_SECTION m_stCriticalSection;
CDataQueue();
~CDataQueue();
public:
static CDataQueue* getDataQueue(){
if (m_cQueue == NULL){
m_cQueue = new CDataQueue();
}
return m_cQueue;
}
deque <ST_MONITORING_RESULT> getQueue();
void pushDataToQueue(ST_MONITORING_RESULT data);
ST_MONITORING_RESULT popDataFromQueue();
};
#endif
//[DataQueue.cpp]
#include "DataQueue.h"
CDataQueue* CDataQueue::m_cQueue = NULL;
CDataQueue::CDataQueue(){
::InitializeCriticalSection(&m_stCriticalSection);
// m_mutex = PTHREAD_MUTEX_INITIALIZER;
}
CDataQueue::~CDataQueue(){
::DeleteCriticalSection(&m_stCriticalSection);
}
::deque <ST_MONITORING_RESULT> CDataQueue::getQueue(){
return m_deQueue;
}
void CDataQueue::pushDataToQueue(ST_MONITORING_RESULT data){
::EnterCriticalSection(&m_stCriticalSection);
m_deQueue.push_back(data);
::LeaveCriticalSection(&m_stCriticalSection);
}
ST_MONITORING_RESULT CDataQueue::popDataFromQueue(){
::EnterCriticalSection(&m_stCriticalSection);
ST_MONITORING_RESULT data = m_deQueue.front();
m_deQueue.pop_front();
::LeaveCriticalSection(&m_stCriticalSection);
return data;
}
Sitting at the top of the <queue> header from the MS implementaiton of the standard library, we find...
// queue standard header
#pragma once
#ifndef _QUEUE_
#define _QUEUE_
Which means your usage of that identifier for your own header fencepost is precluding the MS header body from being pulled in. Thus, no std::queue for you. Use a different id, preferably something that doesn't violate usage rules for macro constants reserved for the implementation (like this one).
And that, kids, is why we don't use identifiers reserved for implementation usage. For more information, read this question: "What are the rules about using an underscore in a C++ identifier?"
I run this piece of code
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/filesystem/fstream.hpp>
#include <iostream>
using namespace boost::unit_test;
using namespace std;
void TestFoo()
{
BOOST_CHECK(0==0);
}
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
std::cout << "Enter init_unit_test_suite" << endl;
boost::unit_test::test_suite* master_test_suite =
BOOST_TEST_SUITE( "MasterTestSuite" );
master_test_suite->add(BOOST_TEST_CASE(&TestFoo));
return master_test_suite;
}
But at runtime it says
Test setup error: test tree is empty
Why does it not run the init_unit_test_suite function?
Did you actually dynamically link against the boost_unit_test framework library? Furthermore, the combination of manual test registration and the definition of BOOST_TEST_MAIN does not work. The dynamic library requires slightly different initialization routines.
The easiest way to avoid this hurdle is to use automatic test registration
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/filesystem/fstream.hpp>
#include <iostream>
using namespace boost::unit_test;
using namespace std;
BOOST_AUTO_TEST_SUITE(MasterSuite)
BOOST_AUTO_TEST_CASE(TestFoo)
{
BOOST_CHECK(0==0);
}
BOOST_AUTO_TEST_SUITE_END()
This is more robust and scales much better when you add more and more tests.
I had exactly the same issue. Besides switching to automatic test registration, as suggested previously, you can also use static linking, i.e. by replacing
#define BOOST_TEST_DYN_LINK
with
#define BOOST_TEST_STATIC_LINK
This was suggested at the boost mailing list:
The easiest way to fix this is to [...] link with static library.
Dynamic library init API is slightly different since 1.34.1 and this is the
cause of the error you see. init_unit_test_suite function is not called in this
case.
I'm trying to test a library that I've done (Calculus), in QTCreator for Windows.
I've created a main file, and a class in a separate file for the testing. If I compile the example found in http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-test-suite.html it works, and so the example found in http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-nullary-test-case.html also works.
But when I try to compile my project I've a lot (over 500) errors of multiple definitions. Below you can find my files. As you can see I've also tried to put some guard around boost headers, but it does not work. What am I doing wrong?
main.cpp
#include "testcalculus.h"
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
using namespace boost::unit_test;
test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
WRayTesting::TestCalculus xTestCalculus;
test_suite* pxTestSuiteCalculus = BOOST_TEST_SUITE("Test Calculus");
pxTestSuiteCalculus->add(BOOST_TEST_CASE( boost::bind(&WRayTesting::TestCalculus::testCartesianPoint2D, &xTestCalculus)));
framework::master_test_suite().add(pxTestSuiteCalculus);
return 0;
}
testcalculus.h
#ifndef TESTCALCULUS_H
#define TESTCALCULUS_H
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
#include "cartesianpoint2d.h"
#include "cartesianvector2d.h"
namespace WRayTesting
{
/** Class for testing the Calculus project */
class TestCalculus
{
public:
//! Constructor
TestCalculus();
//! Testing class point
void testCartesianPoint2D();
private:
};
} // namespace WRayTesting
#endif // TESTCALCULUS_H
testcalculus.cpp
#include "testcalculus.h"
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
namespace WRayTesting
{
using ::Calculus::CartesianPoint2D;
using namespace boost::unit_test;
/**
* Constructor
*/
TestCalculus::TestCalculus()
{
}
/**
* Test the CartesianPoint2D class.
*/
void TestCalculus::testCartesianPoint2D()
{
// Default constructor
CartesianPoint2D xTestingPoint;
BOOST_CHECK(0.0 == xTestingPoint.getX());
BOOST_CHECK(0.0 == xTestingPoint.getY());
}
} // namespace WRayTesting
Compile output
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:62: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_start(std::ostream&, unsigned long)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:62: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:72: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_finish(std::ostream&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:72: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:80: multiple definition of `boost::unit_test::output::compiler_log_formatter::log_build_info(std::ostream&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:80: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:93: multiple definition of `boost::unit_test::output::compiler_log_formatter::test_unit_start(std::ostream&, boost::unit_test::test_unit const&)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:93: first defined here
debug/testcalculus.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:103: multiple definition of `boost::unit_test::output::compiler_log_formatter::test_unit_finish(std::ostream&, boost::unit_test::test_unit const&, unsigned long)'
debug/main.o:c:/lib/boost/boost/test/impl/compiler_log_formatter.ipp:103: first defined here
...........
You cannot include #include in multiple files within the same test module. You either need to switch to library or put everything inside single file