CMake misinterpret types inside c++ program

Viewed 34

Good day. Building program without using cmake ''' g++ -lpthread src/how2thread.cpp src/main.cpp -ggdb3 -std=c++17 -Wextra ''' produces no errors. Although, using ''' cmake . && make ''' generates following build errors:

[ 25%] Building CXX object CMakeFiles/how2thread_lib.dir/src/how2thread.cpp.obj
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp: In member function 'how2thread::Request how2thread::Scheduler::get_request()':
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:103:67: error: use of deleted function 'std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]'
  103 |         auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);
      |                                                                   ^
In file included from C:/msys64/mingw64/include/c++/12.1.0/mutex:43,
                 from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.hpp:8,
                 from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:4:
C:/msys64/mingw64/include/c++/12.1.0/bits/std_mutex.h:237:7: note: declared here
  237 |       lock_guard(const lock_guard&) = delete;

I specify in my header file, that data_arr_protect is std::mutex object

class Scheduler
{
// class for schedule slicers, processors and collecting data
public:
    Scheduler(const std::vector<char>& data,
              const std::string& mask); // construct and parse data
    Request get_request(); // used to get another batch
    void write_request(Request&&);

    void write_finding(Finding&& find);

    using Find_it = decltype(std::declval<std::vector<Finding>&>().cbegin());
    Find_it cbegin();
    Find_it cend();

    const auto& get_slicing_status(){return is_slicing;} //
    std::string mask;
#ifndef DEBUG_V
private:
#endif
    const size_t slicer_num;
    std::queue<Request> data_arr; // consider switching to deQ
    std::mutex data_arr_protect;//for mt rw to vec // might be switching to semaphores

    std::queue<Actor_processor> proc_instances_q;
    std::queue<Actor_slicer> slicer_instances_q;

    std::vector<Finding> result_arr;
    std::mutex result_protect;//for mt write to vec

protected:
    friend class Actor_slicer; // we need access from slicers to mutexes as they're pretty lowlvl
    std::vector<std::mutex> char_segments_protect;
    std::vector<size_t> finish_line_no;
    std::atomic<size_t> is_slicing; // for break cond 
};

My cmake file looks next

cmake_minimum_required(VERSION 3.10.0)
project(how2thread
        VERSION 0.0.1
        DESCRIPTION "simple mt parser app"
        LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

file(GLOB_RECURSE src_files src/*.cpp)

add_library(how2thread_lib src/how2thread.cpp src/how2thread.hpp)

add_executable(how2thread src/main.cpp)
target_link_libraries(how2thread PRIVATE how2thread_lib)
target_link_libraries(how2thread PRIVATE Threads::Threads)

What can cause compiler's misinterpretation and how i must fix it?

I tried different linking options, as building my how2thread.cpp file with main.cpp file, although it didn't help. And I do not get errors about undefined class or something, so, I guess, header file being included by .cpp one

1 Answers

Nothing is being misinterpreted. The issue is the following line: (Which appears only in the error message, not the code you show. Please always provide a minimal reproducible example!)

auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);

This is copy-initialization of m_lock from the initializer expression which before C++17 required the type to be move-constructible, which std::lock_guard is not. Direct-initialization with auto (e.g. auto m_lock(std::lock_guard<std::mutex>(data_arr_protect));) would also not work for the same reason.

To compile this line you need to use C++17 or later, but you are asking cmake to set C++14 with

set(CMAKE_CXX_STANDARD 14)

So change the 14 to 17.

Or if you require compatibility with C++14, you will have to avoid the auto initialization idiom for non-movable types:

std::lock_guard<std::mutex> m_lock(data_arr_protect);
Related