cereal icon indicating copy to clipboard operation
cereal copied to clipboard

Embedded RapidJSON can conflict with another RapidJSON used by the client (ODR violation!)

Open aurelienrb opened this issue 2 years ago • 1 comments

Hello,

Cereal is embedding its own version of RapidJSON. This embedded version has been patched to use custom include path (cereal/external/rapidjson/ instead of rapidjson/) and macros ( CEREAL_RAPIDJSON_ instead of RAPIDJSON_).

This prevents a conflict at compile time with another RapidJSON used by the client.

But! The RapidJSON symbols are still defined in the same original namespace rapidjson: https://github.com/USCiLab/cereal/blob/v1.3.2/include/cereal/external/rapidjson/rapidjson.h#L118

#define CEREAL_RAPIDJSON_NAMESPACE rapidjson

As a result, if a client uses both Cereal and a different version of RapidJSON (or compiles it with an option such as RAPIDJSON_HAS_STDSTRING) then (s)he ends up with an ODR violation 😢

That's what happened to me: my application works well on Windows 11 and crashes on Windows 10... ODR magic!

I see several options here, that could be combined:

  • modify CEREAL_RAPIDJSON_NAMESPACEto something like cereal::rapidjson or cereal_rapidjson to really isolate the vendored version of RapidJSON from another one that could be used by the client
  • update cmake scripts to allow Cereal to use an external RapidJSON library provided by the user. This is generally done by exposing a cmake option such as USE_EXTERNAL_RAPIDJSON.

I selected the second option. And at the same time, I removed the (forced) dependency on RapidXML because I don't want to embed dependencies I don"t need (I am in a strongly regulated context).

Note that, in my case, all of that is done by a Conan recipe that patches and cleans up Cereal code before packaging it.

What do you think is the best option?

aurelienrb avatar Sep 25 '23 20:09 aurelienrb

true.... You should use same Header Protection Marco with rapidjson and same namespace. OR different Marco and different namespace. NOT different Marco(CEREAL_RAPIDJSON_CEREAL_RAPIDJSON_H_) and same namespace(rapidjson).

wwc7654321 avatar May 26 '25 16:05 wwc7654321