mercredi 2 septembre 2015

How to deal with `boost::detail::variant::void_` spam in error messages?

C++ template error messages are notoriously hard to read sometimes, however in a project I am working on the problem is greatly aggravated by the fact that when I use boost::variant the type seems to get padded out by 17 copies of the type boost::detail::variant::void_. The error messages would be much easier to read I think if I could cut out that cruft.

Example backtrace:

#8  0x00000000018538fc in std::allocator_traits<std::allocator<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> > >::allocate(std::allocator<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> >&, unsigned long) ()
#9  0x00000000018538a6 in std::_Vector_base<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, std::allocator<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> > >::_M_allocate(unsigned long) ()
#10 0x000000000185383f in std::_Vector_base<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, std::allocator<boost::variant<std::string, quoted_string, boost::recursive_wrapper<macro_syntax>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> > >::_M_create_storage(unsigned long) ()

A few possible resolutions come to mind:

  1. Adjust a macro or template parameter exposed by boost (does it exist?) such that boost::variant is limited to contain only 5 or 6 types and doesn't pad itself out with so much void_ cruft.

  2. Typedef boost::variant::detail::void_ to something with a really short name, or even just a series of underscores, and somehow convince the compiler to use that name instead in the error messages.

  3. Run all the compiler error messages through a program, maybe even just a sed script, that chops out instances of string , boost::detail::variant::void_

Which of these, if any, work / is the best? Is there a better way I didn't think of / don't know about?

why std::unique_ptr vector gets invalid pointer exception

I wrote simple code to help me understand smart pointers:

string s = "str";
vector <unique_ptr<string>> pv ;

pv.push_back(unique_ptr<string>(&s));
cout<<*(pv[0])<<endl;

This code compiles fine, but gets me a runtime error:

str * Error in `...': munmap_chunk(): invalid pointer: 0x00007ffd956e57e0 * Aborted (core dumped)

What happened and what have I done wrong?

Does CMAKE expects headers and code to be in the same folder?

I have done some simple CMAKE files on small projects. This project was thrown in to my hands and i am trying to make a simple CMAKE file (for scalability). It comes with 2 .cc files (mains) and 3 folders (CLASSES, HANDLERS and INCLUDE). INCLUDE has all the header files (both .h and .hh). I am trying to wrap this up (reading CMAKE documentation and examples) but could not answer this question.

My CMAKE:

cmake_minimum_required(VERSION 3.2)

project(deti_boot_fbp)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SRC "AuthenticatedFileBroadcast/src") set(CLASSES "AuthenticatedFileBroadcast/src/classes") set(HANDLERS "AuthenticatedFileBroadcast/src/handlers") set(INCLUDE "AuthenticatedFileBroadcast/src/include") set(SOURCE_FILES_CLIENT ${SRC}/fbp-client.cc)

file(GLOB SOURCE_FILES RELATIVE "${CLASSES}" ".{cc,cpp}" "${HANDLERS}" ".{cc,cpp}" "${INCLUDE}" "*.{hh,h}")

INCLUDE_DIRECTORIES (${SRC} ${CLASSES} ${HANDLERS} ${INCLUDE} )

add_library(deti_boot_lib SHARED ${SOURCE_FILES}) SET_TARGET_PROPERTIES(deti_boot_lib PROPERTIES LINKER_LANGUAGE CXX)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/binn) set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)

add_executable( deti_boot_fbp ${SOURCE_FILES_CLIENT})

target_link_libraries( deti_boot_fbp deti_boot_lib) target_link_libraries( deti_boot_fbp crypto pthread z dl)

The final result is that the main (fbp-client) is not linked to my own methods (deti_boot_lib)

c++ template auto parameter

I am trying to write a logging routine that (almost) automatically traces the entry and exit to a method. Something like:

int rc=0;
LOG_ENTRY("MyFunction()", rc);

LOG_ENTRY is a macro that defines a local object. When the object is created it will call the logger with "Entry MyFunction()" and when the object is destroyed at the end of the traced method, the destructor will issue "Exit MyFunction() returned 0" where 0 is the value of rc on exit.

Now I have most of this working using c++ except that the constructor for the class for the logging object has to be defined for every type of return value:

class IM_EX_CTIBASE LogEntry
{
    Log *logger;
    const char* func;
    void *rc;
public:
    LogEntry(Log *logger, const char* func, int *rc)
    {
        this->logger=logger;
        this->func=func;
        this->rc=rc;
        logger->log("Entry " << func);
    }
    ~LogEntry()
    {
        logger->log("Exit " << func << *rc);
    }
}

(please forgive any typos, this is a simplified version of the actual code.)

Now I was hoping to rewrite this as a template, where the type rc could be externally defined. I was thinking that auto would be an excellent possibility for defining rc on the constructor, but auto does not work there.

Since the compiler already knows what the type is, why do I need to define it here. the log() (which accepts a stream) should already know how to use rc.

I've looked at many alternatives, but nothing seems to be what I want. Someone suggested "do it like make_pair does", but after digging into that it appears to create a function template which I don't think you can use in a constructor.

Anyone have any ideas?

Ensure that class derived from parent CRTP class implements function

Brief:

I want to make sure a derived class implements a member function required by a function within the parent CRTP class.

Detail:

I have some code like this

class Base
{
public:
    class Params
    {
    public:
        virtual ~Params() {}
    };

    virtual void myFunc( Params& p ) = 0;
};

template< typename T >
class CRTP : public Base
{
public:
    virtual void myFunc( Base::Params& p ) override
    {
        typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
        static_cast<const T*>( this )->myFunc( typeParams );
    }

};

class Imp : public CRTP<Imp>
{
public:
    class Params : public CRTP<Imp>::Params
    {
    public:
        virtual ~Params() {}

        int x, y, z;
    };

    virtual void myFunc( Imp::Params& p );
};

The intention is that I can have multiple Imp child classes all doing different things in myFunc and accepting their own required parameters. The interface provided by Base is then utilized by higher level functions that only need to have a pointer/reference of type Base::Params and Base. My problem is making sure that any Imp provides a specialized myFunc. To avoid infinite recursion Imp must implement myFunc.

My first try was adding a pure virtual function to CRTP

virtual void myFunc( typename T::Params& p ) = 0;

but that doesn't work as Imp hasn't been fully defined when CRTP is being defined. This question uses a static_assert which made me think of doing the same with the static_assert within CRTP::myFunc. Except I'm not sure what should be the expression in the static assertion for a non-static function.

  1. Can I use a static_assert for what I need?
  2. Is that the best/cleanest way to ensure the derived class has the needed function?
  3. Have I got carried away with my class design and there is a better way of doing things?

Thanks.

Why "move semantics" rather than simply memcpy?

Given the following code:

typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_t;

//this moves the back of src to the back of dst:
void push_popped(std::list<storage_t> & dstLst, std::list<storage_t> & srcLst)
{
  auto & src = srcLst.back();
  dstLst.push_back(storage_t());
  auto & dst = dstLst.back();
  std::memcpy(&dst, &src, sizeof(T));
  srcLst.pop_back();
}

I'm aware of 3 reasons why this approach is not, in general, correct (even though it avoids calling src->~T() and so avoids double-reclamation of T's resources).

  1. class member pointers that point to other class members
  2. hidden class members may need to be updated (vtable, for instance)
  3. the system needs to record that no T exists anymore at src and that a T does now exist at dst

(These are mentioned here: http://ift.tt/1IIOMCz.)

Assuming that T is not a type whose memory address is a property of its state (std::mutex or std::condition_variable, for instance), are these the only issues with this approach? Or are there other things that could go wrong? I'd like a description of the unknown issues.

I'd like to think I have an "object relocation semantics" developed, but I'd rather not ask people to consider it if there's an obvious hole in it.

optional range check based on template parameter

Let's say i have a class that simply performs addition for any type T. I want to add an optional range check (based on a template parameter of type bool), that will check whether the result of the addition belongs in a given range, or else it will throw. One way of doing this, is wrapping all basics of the class in a base class and then specialize on the boolean template parameter. Something like:

// The base class; holds a starting value to add to and a maximum value
template<typename T>
class DummyImpl
{
private:
  T mval, mmax;

public:
  constexpr explicit DummyImpl(T x, T max_x) noexcept
 : mval{x}, mmax{max_x}
  {};

  // base class; use a virtual destructor
  virtual ~DummyImpl() {};

  T max() const noexcept {return mmax;}
  T val() const noexcept {return mval;}
};

// The "real" class; parameter B denotes if we want (or not)
// a range check
template<typename T, bool B>
class Dummy : DummyImpl<T> {};

// Specialize: we do want range check; if sum not in range
// throw.
template<typename T>
class Dummy<T, true> : DummyImpl<T>
{
public:
  explicit Dummy(T x, T max_x) noexcept : DummyImpl<T>(x, max_x) {};

  T add(T x) const noexcept( !true )
  {
    T ret_val = x + DummyImpl<T>::val();
    if (ret_val < 0 || ret_val > DummyImpl<T>::max()) {
      throw 1;
    }
    return ret_val;
  }
};

// Specialize for no range check.
template<typename T>
class Dummy<T, false> : DummyImpl<T>
{
public:
  explicit Dummy(T x, T max_x) noexcept : DummyImpl<T>(x, max_x) {};

  T add(T x) const noexcept( !false )
  {
    return x + DummyImpl<T>::val();
  }
};

Now the user can write code like:

int main()
{
  Dummy<float,false> d(0, 1000); //no range check; never throw

  std::cout <<"\nAdding  156.7 gives " << d.add(156.7);
  std::cout <<"\nAdding 3156.7 gives " << d.add(3156.7);

  std::cout <<"\n";
  return 0;
}

Is there a way of doing this without using inheritance? I would suppose that using a nested class would be more efficient, but the following code does not compile.

template<typename T,  bool RC>
class Dummy
{
private:
  T mval, mmax;

  // parameter S is only used to enable partial specialization on
  // parameter I
  template<bool I, typename S> struct add_impl {};

  template<typename S> struct add_impl<true, S>
  {
    T operator()(T x) const noexcept( !true )
    {
      T ret_val = x + mval;
      if (ret_val < 0 || ret_val > mmax) {throw 1;}
      return ret_val;
    }
  };

  template<typename S> struct add_impl<false,  S>
  {
    T operator()(T x) const noexcept( !false )
    {
      return x + mval_ref;
    }
  };

public:
  constexpr explicit Dummy(T x, T max_x) noexcept
 : mval{x}, mmax{max_x}
  {};

  void bar() const { std::cout << "\nin Base."; }
  T max() const noexcept {return mmax;}
  T val() const noexcept {return mval;}
  T add(T x) const noexcept( !RC )
  {
    return add_impl<RC, T>()(x);
  }
};


int main()
{
  Dummy<float,false> d(0, 1000);

  std::cout <<"\nAdding  156.7 gives " << d.add(156.7);
  std::cout <<"\nAdding 3156.7 gives " << d.add(3156.7);

  std::cout <<"\n";
  return 0;
}

It fails with an error message (in g++):

error: invalid use of non-static data member ‘Dummy<float, false>::mval’

Is there a way around this? If so, is it more efficient than the first solution? Will the nested class add size to any instance of Dummy? Is there a more elegant design/implementation?