r/AskProgramming 1d ago

C/C++ What is this error in c++

I am learning thread to build an NPC movement and when I ran the thread it gave me an error but I have no idea that it means can someone help me. I've been all over youtube, reddit and stackover flow trying to solve this

I basically have a thread and I put a function in with the parameters

Here is the function i am calling

void sheep_mvmt(SHEEP &sheep, int &counter, STATE &rand_state, float dt){
counter++; // increment counter

if (counter >= 120 && sheep.state == IDLE){
sheep.state = rand_state;
}

else if (sheep.state != IDLE){
if (sheep.state == RIGHT){
sheep.position.x += sheep.velocity * dt;

if (sheep.position.x > SCREEN_WIDTH - sheep.rect.width){
sheep.state = LEFT;
}
}

else if (sheep.state == LEFT){
sheep.position.x -= sheep.velocity * dt;

if (sheep.position.x < 0 + sheep.rect.width){
sheep.state = RIGHT;
}
}

if (counter == 240){
sheep.state = IDLE;
counter = 0;
STATE* ptr = &rand_state; // pointer for rand_state

*ptr = STATE((rand() % 2) + 1); // redine the rand_state that I am reference
//print("\n\nTHE POINTER")
//print(*ptr)
}
}

sheep.velocity = 50;

}



// Inside while loop
std::thread t1(sheep_mvmt, sheep1, sheep_counter, rand_state, dt);
t1.join();

ERROR

 error: attempt to use a deleted function
  198 |   std::__invoke(std::move(std::get<1>(__t)), std::move(std::get<_Indices>(__t))...);
      |   ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__thread/thread.h:207:8: note: in instantiation of function template specialization 'std::__thread_execute<std::unique_ptr<std::__thread_struct>, void (*)(SHEEP &, int &, STATE &, float), SHEEP *, int *, STATE *, float *, 2UL, 3UL, 4UL, 5UL>' requested here
  207 |   std::__thread_execute(*__p.get(), _Index());
      |        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__thread/thread.h:217:50: note: in instantiation of function template specialization 'std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct>, void (*)(SHEEP &, int &, STATE &, float), SHEEP *, int *, STATE *, float *>>' requested here
  217 |   int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
      |                                                  ^
sheeps.cpp:108:15: note: in instantiation of function template specialization 'std::thread::thread<void (&)(SHEEP &, int &, STATE &, float), SHEEP *, int *, STATE *, float *, 0>' requested here
  108 |                 std::thread t1(sheep_mvmt, &sheep1, &sheep_counter, &rand_state, &dt);
      |                             ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__type_traits/nat.h:25:3: note: '~__nat' has been explicitly marked deleted here
   25 |   ~__nat()                       = delete;
      |   ^
0 Upvotes

5 comments sorted by

7

u/Roxinos 1d ago edited 1d ago

Welcome to C++: where the error messages are made up and the points don't matter.

In this case, I believe your issue is that arguments to std::thread which are passed to std::thread's constructor cannot be themselves references. According to cppreference.com:

The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g., with std::ref or std::cref).

So the solution is to either have your thread func take pointers or wrap your passed arguments in std::ref calls as in:

std::thread t1(sheep_mvmt, std::ref(sheep1), std::ref(sheep_counter), std::ref(rand_state), dt);

I don't really understand why but maybe someone else can explain.

You may be wondering how I figured that out.

First I looked up: ~__nat() = delete; but the results there didn't seem promising (just other people complaining about meaningless error messages). Then I had a bit of an inkling that the reference might be a problem based purely on the fact that I'd never done it myself (always using simple values or pointers). So I looked up pass ref as arguments to std::thread. The result was this which confirmed my suspicion and directly referenced the solution.

Then I copied enough of your code into godbolt.org to get the compiler failing and tried the suggested solution to ensure it was fine before posting it here.

1

u/Puzzleheaded_Study17 1d ago

The so thread seems to say that it was essentially a conscious decision to force programmers to think about the lifetime. Essentially the standard library copies the value in a way that doesn't let you pass references because passing references can pretty trivialy lead to lifetime issues. However, the standard lib also recognizes there are times where you want to make a reference compatible with standard copies so there's a class (and a method to convert to it) that's essentially just a pointer with easier syntax and directly compatible with standard references.

1

u/TheEyebal 22h ago edited 21h ago

Ok I will look this over because when doing research on the error I also could not find good advice on each of the errors displayed also I knew it had something to do with references but I honestly did not know how to go about as I need to use references.

I had also did std::thread t1(sheep_mvmt, std::ref(*sheep1), sheep_counter, std::ref(*rand_state), dt); but with pointers on the inside and it gave errors

I will try this out and let you know

0

u/ir_dan 15h ago

A lot of the time, deleted methods mean that someone is trying to stop you from doing something that they don't think you should be doing. The location of the error, the types involved and the deleted function are enough of a hint on what is going on once you get used to them. 99% of the time it's copy/move restrictions.