3

I'm new to threads handling and I'm getting a bit confused as of why this bit of code doesn't work :

// Note that the GKITH object is useful for my whole code
void thread_function( gkit2light_Handler*& GKITH )
{
    std::cout << "\t~ Writing from gkit2light thread..." << std::endl;
}

int main( int argc, char** argv )
{

    // Custom gkit2light Handler
    gkit2light_Handler *gkit_handler = new gkit2light_Handler( );

    // Launching thread...
    std::thread gkit_thread( thread_function, gkit_handler );

    return 0;

}

I run it under macOS 10.13 using XCode 9. None of these lines actually throws me an error but my compiler gives me this message : « Attempt to use a deleted function ». This is weird because here the thread_function( ) only accesses the stdout...

Here it the deleted function, maybe this can help you !

struct __nat
{
#ifndef _LIBCPP_CXX03_LANG
    // ...

    // This is the destructor that is throwing the error
    ~__nat() = delete;
#endif
}; 

Here is a screenshot of the error (there isn't any more info): XCode compiler error screenshot

Fumée Noire
  • 93
  • 1
  • 8
  • Which line is the compiler complaining about? (Please [edit] the question to include the whole of the compiler error message.) – Martin Bonner supports Monica Mar 12 '18 at 12:35
  • 1
    Possible duplicate? https://stackoverflow.com/questions/43237503/starting-a-member-function-with-arguments-in-a-separate-thread – Galik Mar 12 '18 at 12:36
  • Well I need to create a thread for parallel calculation (image processing) but because I got this error, I tried to simplify the code and I ended with this, still giving me the same error ! – Fumée Noire Mar 12 '18 at 12:40
  • You are wrong. There is additional information there. Which is `main.cpp` line 9? (Also, please learn how to display the actual compiler output, and not copy that into the question.) – Martin Bonner supports Monica Mar 12 '18 at 12:40
  • 1
    Also read [mcve] – Passer By Mar 12 '18 at 12:41
  • You are doing quite well, at getting towards a MCVE, and very well at actually editing the question, rather than answering in comments, but my theory is the the compile error is happening in or around the call to `new` (so we don't need the subsequent lines). – Martin Bonner supports Monica Mar 12 '18 at 12:43
  • Try to add `std::ref(gkit_handler)` in thread ctor. – rafix07 Mar 12 '18 at 12:46
  • Well I checked the thread Galik posted here and I found that by switching to a std::ref( gkit_handler ) inside the thread creation gets rid of the error ! – Fumée Noire Mar 12 '18 at 12:48
  • I trust that you're doing more than that between starting a thread and joining it in main? Otherwise you may as well not have the thread at all. – UKMonkey Mar 12 '18 at 12:56
  • What I think Martin is trying to say is that you should remove lines of code until _only the bare minimum remains_. Without the `joinable` and `join` the error would still be visible - thus you don't need them in your example. Or keep it to express intent, but comment them or somehow indicate that it is because of the `std::thread ..` line that the error happens. You haven't done that atm. – default Mar 12 '18 at 12:57
  • Oh ok understood :-) – Fumée Noire Mar 12 '18 at 13:01
  • I take it, then, that `__nat` is inside the toolchain's code somewhere – Lightness Races in Orbit Mar 12 '18 at 13:05
  • this also looks related: https://stackoverflow.com/questions/29191445/c-stdthread-attempt-to-use-a-deleted-function – default Mar 12 '18 at 13:40

1 Answers1

3

You cannot bind a reference like this while passing arguments to thread (and this is stated in at least one reference). To pass a reference, use std::ref to wrap it. This will survive the move/copy that happens to those arguments.

It's a shame that the toolchain kicks out such an arcane error message, but it means that somewhere within its template metaprogramming it's trying and failing to instantiate some templates relating to the code you wrote.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • but like you noted yourself, it's a pointer. Copying a pointer shouldn't call any destructors, right? – default Mar 12 '18 at 13:09
  • 1
    @Default: It doesn't, but somewhere inside the vastly complicated mechanism of `std::thread`, and everything relate to it, instantiation of some template related to the act of doing something impossible has resulted in this error. It's not a pointer argument, but a reference argument, and you can't "copy a reference". We could trace the entire chain of events but only when really bored. – Lightness Races in Orbit Mar 12 '18 at 13:09
  • ah, it's because of the functions argument list then? the argument `gkit2light_Handler* GKITH` (without the `&`) wouldn't have triggered it perhaps? – default Mar 12 '18 at 13:13
  • @Default: That's what I'm surmising. If you can remove the `&` and the problem still happens then I have _no_ idea what's going on :) – Lightness Races in Orbit Mar 12 '18 at 13:17
  • 1
    I managed to trigger this rather unenlightening error message by failing to include the required number of arguments for the target function I provided. – AnOccasionalCashew Nov 11 '20 at 05:09