[CXX-1688] MongoDB CXX driver does not compile with standard polyfill. Created: 06/Nov/18  Updated: 28/Oct/23  Resolved: 15/Nov/18

Status: Closed
Project: C++ Driver
Component/s: Build
Affects Version/s: 3.4.0
Fix Version/s: 3.5.0, 3.4.1

Type: Bug Priority: Major - P3
Reporter: Piotr Szczepanski Assignee: Kevin Albertson
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Ubuntu 18.04/Arch, GCC 8.2.0


Issue Links:
Duplicate
is duplicated by CXX-1737 Driver fails to compile on MSVC 2017 ... Closed
is duplicated by CXX-1710 Failed to compile version 3.4.0 with ... Closed
Related
is related to CXX-1689 database::_create_collection is not u... Closed

 Description   

When trying to build MongoCXX driver with standard polyfill, the build fails.

Steps to reproduce:

cd mongo-cxx-driver/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 ..
make

CMake does state that it will be using C++17 std library polyfills:

-- The CXX compiler identification is GNU 8.2.0
-- The C compiler identification is GNU 8.2.0
-- Auto-configuring bsoncxx to use C++17 std library polyfills since C++17 is active and user didn't specify otherwise
{code]
 
Running make fails with:
 
{code:java}
In file included from /github/mongo-cxx-driver/src/mongocxx/private/client_session.hh:24,
                 from /github/mongo-cxx-driver/src/mongocxx/bulk_write.cpp:25:
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh: In member function 'std::optional<mongocxx::v_noabi::read_concern> mongocxx::v_noabi::options::transaction::impl::read_concern() const':
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh:64:88: error: could not convert '{std::make_unique(_Args&& ...) [with _Tp = mongocxx::v_noabi::read_concern::impl; _Args = {_mongoc_read_concern_t*}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<mongocxx::v_noabi::read_concern::impl>]()}' from '<brace-enclosed initializer list>' to 'std::optional<mongocxx::v_noabi::read_concern>'
         return {stdx::make_unique<read_concern::impl>(libmongoc::read_concern_copy(rc))};
                                                                                        ^
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh: In member function 'std::optional<mongocxx::v_noabi::write_concern> mongocxx::v_noabi::options::transaction::impl::write_concern() const':
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh:77:90: error: could not convert '{std::make_unique(_Args&& ...) [with _Tp = mongocxx::v_noabi::write_concern::impl; _Args = {_mongoc_write_concern_t*}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<mongocxx::v_noabi::write_concern::impl>]()}' from '<brace-enclosed initializer list>' to 'std::optional<mongocxx::v_noabi::write_concern>'
         return {stdx::make_unique<write_concern::impl>(libmongoc::write_concern_copy(wc))};
                                                                                          ^
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh: In member function 'std::optional<mongocxx::v_noabi::read_preference> mongocxx::v_noabi::options::transaction::impl::read_preference() const':
/github/mongo-cxx-driver/src/mongocxx/options/private/transaction.hh:90:89: error: could not convert '{std::make_unique(_Args&& ...) [with _Tp = mongocxx::v_noabi::read_preference::impl; _Args = {_mongoc_read_prefs_t*}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<mongocxx::v_noabi::read_preference::impl>]()}' from '<brace-enclosed initializer list>' to 'std::optional<mongocxx::v_noabi::read_preference>'
         return {stdx::make_unique<read_preference::impl>(libmongoc::read_prefs_copy(rp))};

When using MNMLSTC, everything is working fine.



 Comments   
Comment by Githook User [ 15/Nov/18 ]

Author:

{'name': 'Piotr Szczepanski', 'email': 'piotr.szczepanski@avast.com', 'username': 'tamaroth'}

Message: CXX-1688 Fix building with GCC 8.x
Branch: master
https://github.com/mongodb/mongo-cxx-driver/commit/913a41937937ac518d817c7e6c95994915587543

Comment by Kevin Albertson [ 08/Nov/18 ]

I checked with gcc 8.2 and agree with your analysis. I confirmed that your patch fixes this on my end. I commented in the pull request requesting a small change.

Thank you for the great work!

Comment by Piotr Szczepanski [ 08/Nov/18 ]

I have found a reason for the failure.

When constructing std::optional, the underlying object (read_concern, write_concern, and read_preference) is created inside std::optional as the object is not created in-place and as a result it does not have access to the private constructor of that class.

To circumvent this, we have to create the object explicitly in the transaction::impl method and then create an stdx::optional<> from already existing object (using constructor #8 of optional).

My pull request now reflects this fact. Please confirm on your end and let me know if you came to the same conclusions.

Thanks for your time!

Comment by Kevin Albertson [ 07/Nov/18 ]

Thank you for your the bug report and contribution!

It isn't clear to me why this is necessary. Since options::transaction is declared as a friend of read_concern and read_preference I'd think that options::transactions::impl would have access to the private constructors of read_concern and read_preference.

I'll reproduce on GCC 8.x and investigate.

Comment by Piotr Szczepanski [ 07/Nov/18 ]

I have created a ticket for the string conversion:
https://jira.mongodb.org/browse/CXX-1689

For the current ticket, I have created a pull request that solves the issue:
https://github.com/mongodb/mongo-cxx-driver/pull/638

Comment by Piotr Szczepanski [ 07/Nov/18 ]

Additionally, when the abovementioned classes are fixed, there is another error:

/github/mongo-cxx-driver/src/mongocxx/database.cpp:230:38: error: ‘using string_view = class std::basic_string_view<char>’ {aka ‘class std::basic_string_view<char>’} has no member named ‘to_string’
         _get_impl().database_t, name.to_string().c_str(), opts_bson.bson(), &error);

Which can be fixed (for all polyfill variants) by replacing name.to_string().c_str() with name.data().

Comment by Piotr Szczepanski [ 07/Nov/18 ]

It seems the culprit is the private constructor of the read_concern, write_concern, and read_preference classes that take a unique ptr to their implementation.

If you make that constructor public, everything is compiling without a problem.

Generated at Wed Feb 07 22:03:35 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.