Project

General

Profile

Compiling Wt with std::any

Added by Chris Hengler over 4 years ago

I'm working on a project where I'm storing data in models and then retrieving it later, casting back from Wt::cpp17::any to the appropriate type.

I see from the release notes that since Wt version 4.0 the Wt::cpp17::any implementation is configurable, and std::any can be used. I'm using version 4.1.1, but I'm having difficulty building Wt with the std::any implementation.

Here's a simplified example section of my code to illustrate how I'm using it:

  //create 'v', a vector of WStandardItem objects

  int newRow = model->rowCount();
  model->insertRow(newRow, std::move(v));
  EventStatus status{event.getCriticality(), event.getSuppression()};
  model->setData(newRow, STATUS_COLUMN, status, Wt::ItemDataRole::User);

Wt::cpp17::any data = model->data(index.row(), STATUS_COLUMN, Wt::ItemDataRole::User);
try{
  auto status = Wt::cpp17::any_cast<EventStatus>(data);
  //do some stuff with status variable
}
catch(const std::exception &e) {
  //error handling
}

My code functions as intended when I use Wt::cpp17::any and Wt::cpp17::any_cast. If I try to replace these with the std equivalents I'm still able to compile and run, but any std::any_cast results in std::bad_any_cast being thrown.

So far I have set CMAKE_CXX_STANDARD to 17 in the CMakeLists.txt file in the top Wt directory. Based on my reading of the CMake file (which may be wrong, I'm certainly no CMake expert) this should lead to the variable WT_CPP17_ANY_DEFAULT_IMPLEMENTATION being set to "std", which should then lead to WT_CPP17_ANY_IMPLEMENTATION being set to "std", which should lead to SET (WT_ANY_IS_STD_ANY ON). I'd have expected this to allow me to use std::any_cast with data from (for example) [WAbstractItemModel->data()](https://webtoolkit.eu/wt/doc/reference/html/classWt_1_1WAbstractItemModel.html#af77f707dd2340652717e7122cd7f4ffd), but that seems not to be the case (as I described above, there are no errors or warnings at compilation, but at runtime any attempt to cast results in a bad_any_cast).

How do I resolve this?


Replies (7)

RE: Compiling Wt with std::any - Added by Roel Standaert over 4 years ago

Did you configure it with -DCMAKE_CXX_STANDARD=17, or did you set it later on? Because WT_CPP17_ANY_IMPLEMENTATION is cached, changing CMAKE_CXX_STANDARD later on doesn't update it, and you have to set it to std yourself.

RE: Compiling Wt with std::any - Added by Chris Hengler over 4 years ago

Yes, that seems to be the problem. I'd built the library for the first time without setting the standard. Now I've cleaned everything out and rebuilt, setting the standard at the first build, and everything is working as intended with std::any.

Thanks for your help!

Chris

RE: Compiling Wt with std::any - Added by Stefan Bn over 4 years ago

I ran into the same problem!

Compiling Wt 4.1.2 using MingGW 64 bit/Windows with -DCMAKE_CXX_STANDARD=17 flag set. WT_CPP17_ANY_IMPLEMENTATION automatically sets to "std" and compilation of the (shared) wt libraries is fine.

However my app, also compiled from clean with -DCMAKE_CXX_STANDARD=17, crashes with bad_any cast at runtime. I temporarily removed all any_casts from my code and the app still crashes somewhere around a DBO database access. I have no further way to "tune" my application code, as all the any_casts already have been removed.

I guess the Wt lib itself does certain any_casts during application runtime? Is there any way to come closer and find out whats wrong?

(I just recompiled Wt 4.1.2 lib with WT_CPP17_ANY_IMPLEMENTATION set to default 'thelink2012' and everything is fine again)

RE: Compiling Wt with std::any - Added by Roel Standaert over 4 years ago

Stefan: so you're saying that parts of your Wt build were built with std::any and parts of it used Wt's bundled any implementation?

RE: Compiling Wt with std::any - Added by Stefan Bn over 4 years ago

so you're saying that parts of your Wt build were

built with std::any and parts of it used Wt's

bundled any implementation?

I've built the Wt 4.1.2 lib with the bundled any implementation 'thelink2012'.

My own code that links against those Wt-Libs uses multiple std::any_cast's and everything is running perfect.

However, when I built Wt 4.1.2 lib with std::any implementation then my app crashes, even when my own code doesn't have any_casts.

RE: Compiling Wt with std::any - Added by Roel Standaert over 4 years ago

Do the Wt headers match the build? One thing I'm thinking may be an issue is: if a function has the same signature, but a different return type (std::any vs the included any implementation) that can blow up at runtime.

RE: Compiling Wt with std::any - Added by Stefan Bn over 4 years ago

I was struggeling with this issue when building current version 4.2.0 with std::any. I found out that this is an issue of MinGW under Windows when std::any is used across shared libraries (as this the case for my Wt libs) as described here:

https://stackoverflow.com/questions/45290296/stdany-across-shared-library-bounding-in-mingw?rq=1

The patch proposed there worked for me. So far no more bad_any_casts ...

    (1-7/7)