Re: [Quickfix-developers] Confused by possible bug in Utility.cpp / thread_spawn
Brought to you by:
orenmnero
From: K. F. <kfr...@gm...> - 2013-01-17 13:16:45
|
Hello Djalma! Thanks for taking a look at this. On Thu, Jan 17, 2013 at 7:17 AM, Djalma Rosa dos Santos Filho <drs...@gm...> wrote: > > Hi Frank, > > Is the name of the function the function pointer itself? As I understand c++ (and c), yes. When you use the name of a it "decays" into a function pointer (in the same way that the name of an array decays into a pointer to the first element of the array). > IMHO, this is just a matter of syntax and compiler implementation detail. > You might want to check the C99 spec and the compiler documentation. It is syntax, but I think it's standardized, and therefore it shouldn't be a compiler-specific detail. Also, the unix branch for the code (line 488 of Utility.cpp): if( pthread_create( &result, 0, func, var ) != 0 ) return false; does not have the '&' on "func" and compiles fine. Note, that "func" is not the name of a function, but rather a formal argument to the thread_spawn function (line 479): bool thread_spawn( THREAD_START_ROUTINE func, void* var, thread_id& thread ) (If I parse the typedef of THREAD_START_ROUTINE correctly, THREAD_START_ROUTINE is indeed a pointer to a function in both the windows and unix branches of the code.) So the unix branch looks right -- func is a function pointer, and there is no '&' to take the pointer to the pointer. But the windows branch (line 484): result = _beginthreadex( NULL, 0, &func, var, 0, &id ); has the '&' so "&func" is a pointer to func (the address of wherever func is stored on the stack when thread_spawn is called), and func is a pointer to a function, so "&func" is, as I read t, a pointer-to-pointer-to-function. What I don't understand, following up on Mike's comment, is why this would compile with visual studio. (I don't have visual studio to test.) To me it looks like a straightforward c++ issue. Either visual studio is doing something non-standard (wrong), of I've missed a different typedef hidden somewhere in an #ifdef somewhere in the windows branch of the code. (But, if so, it would be a typedef that mingw-w64 isn't picking up on.) So I think "&func" is an error. But I am also puzzled, because it compiles with visual studio, which doesn't make sense to me. > Djalma Thanks for your help. K. Frank > On Tue, Jan 15, 2013 at 8:05 PM, K. Frank <kfr...@gm...> wrote: >> >> Hi Mike! >> >> On Tue, Jan 15, 2013 at 1:10 PM, Mike Gatny <mg...@co...> wrote: >> > It works with the VS compiler (32-bit, anyway). Can you post the actual >> > error message that mingw-w64 is giving you? >> >> Yes, I'd be happy to post the mingw-w64 error message. >> >> But before I do, I would like to check whether the code looks to you >> like it has an error, or whether I'm missing something simple about >> relatively basic c++. (Again the issue is that I see a >> pointer-to-pointer-to-function (double pointer) being passed, while a >> pointer-to-function (single pointer) is expected.) Does this look >> like an error to you? >> >> Anyway, here's the mingw-w64 error message: >> >> Utility.cpp: In function 'bool FIX::thread_spawn(unsigned int >> (*)(void*), void*, FIX::thread_id&)': >> Utility.cpp:510:56: error: cannot convert 'unsigned int >> (**)(void*)' to 'unsigned int (*)(void*)' for argument '3' to >> 'uintptr_t _beginthreadex(void*, unsigned int, unsigned int >> (*)(void*), void*, unsigned int, unsigned int*)' >> >> In a way, I'm not surprised that you don't see the issue with visual >> studio, because if you did, you would have changed the code. So >> I wonder whether visual studio might be doing something wrong or >> non-standard here. (I'm not aware of anything, but I'm not that >> expert with visual studio.) Or maybe g++ / mingw-w64 is doing >> something non-standard. But again, when I parse the code by >> eye, I come up with a type mismatch. >> >> (Just to note, the linux builds with g++ wouldn't have caught this >> because this is in the windows-specific part of the threading code. >> I verified -- at least to my eye -- that the analogous posix-threading >> part of the code doesn't have this issue.) >> >> By the way, if I "fix" the code by changing >> >> result = _beginthreadex( NULL, 0, &func, var, 0, &id ); >> >> to >> >> result = _beginthreadex( NULL, 0, func, var, 0, &id ); >> >> (that is, removing what appears to be the extra '&' from "&func") >> the code compiles under mingw-w64. I don't know whether the >> code runs correctly because I haven't been able to compile all >> of the rest of the code. But I would be worried about just making >> this change blindly because there is something going on that I >> don't understand. >> >> Thanks for helping me sort this out. >> >> K. Frank >> ... |