2

I am trying to understand some legacy code using AfxBeginThread.

To my understanding LPVOID is defined as a pointer to a void object. I have this function:

Start(LPVOID pParam){
...
   int iTemp = (int)pParam;
...
}

And then the call:

int ch1 = 1;
AfxBeginThread(Start(), (LPVOID)ch1);

I am getting the following compiler warning when compiling for 64bit:

warning C4312: 'type cast': conversion from 'int' to 'LPVOID' of greater size

I am

  • not 100% sure this is a proper use of a pointer
  • to avoid the warning, I could use a helper function like (LPVOID) PtrToInt(ch1), but that doesn't look right to me as well

Could anyone help me understand the mechanics behind this? I've been trying to find an example online which uses AfxBeginThread in a similar fashion but failed so far.

MS states:

The parameter is a single value. The value the function receives in this parameter is the value that was passed to the constructor when the thread object was created. The controlling function can interpret this value in any manner it chooses. It can be treated as a scalar value or a pointer to a structure containing multiple parameters, or it can be ignored.

womdom
  • 55
  • 1
  • 6
  • 1
    If you're sticking with the Windows API and care not about platform independence (clearly not), [`LONG_PTR`](https://learn.microsoft.com/en-us/windows/desktop/WinProg/windows-data-types) as the type for `ch1` would guarantee no oddities, as it freely can be cast to/from general windows "usefull" pointer types (such as `LPVOID`). – WhozCraig Aug 31 '18 at 06:38

2 Answers2

4

This warning occurs because you are compiling on a 64 bit machine where sizeof(void*) is 8 bytes but sizeof(int) is 4.

A proper way to handle this would be to use an integer type for ch1 which is the same size as a void pointer. This is the exact use case for intptr_t.

And so, it should be safe if you use ìntptr_t to hold the ch1 variable. See also this question: C++: Is it safe to cast pointer to int and later back to pointer again?

Gilles Gregoire
  • 1,696
  • 1
  • 12
  • 14
  • Thanks for this very helpful hint. I wasn't aware of `intptr_t`. Is it correct that I don't have the stack problem (the thread starting when the stack has already been cleaned) with this solution? – womdom Aug 31 '18 at 06:49
  • Yes, this is correct, `ch1` is passed by value then. – Gilles Gregoire Aug 31 '18 at 07:43
0

not 100% sure this is a proper use of a pointer

You have the right hunch. No, it is not proper use of a pointer.

You can pass a pointer to the function.

int ch1 = 1;
int* ptr = &ch1;
AfxBeginThread(Start(), ptr);
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    I had a similar option in mind. My colleague (i think rightfully) argued that I am then handing over a pointer to the stack and I cannot guarantee that the stack is still available when the thread is executed. Would the IntToPtr solution circumvent that? – womdom Aug 31 '18 at 06:15
  • @womdom, that is a valid concern. I have no experience of using `IntToPtr` but it sounds like something that should work. – R Sahu Aug 31 '18 at 06:23
  • 2
    @wom: [IntToPtr](https://learn.microsoft.com/en-us/windows/desktop/winprog64/the-tools) will work for your use case. You can mirror that with `PtrToInt` in your thread procedure, to extract an `int`. All of the helper functions operate on values, so you won't have to worry about dangling pointers. – IInspectable Aug 31 '18 at 10:43