Why is this code compiling?

Last night, being too tired, I wrote this strange line:

::TerminateThread(::TerminateThread, 0); 

To my surprise, the compiler does not complain (it even starts ...)

Since TerminateThread () is defined as

 BOOL WINAPI TerminateThread(HANDLE hThread, DWORD dwExitCode); 

I am not sure why I can compile it.

Any explanation?

+7
c ++ compilation visual-studio-2008 winapi
source share
4 answers

HANDLE is a pointer to void, and the Microsoft compiler allows you to implicitly convert a pointer to a pointer to void.

This has helped me many times, especially with heap functions:

 HeapAlloc (GetProcessHeap, 0, size); // oops, should be GetProcessHeap() 
+7
source share

It takes the address of the ::TerminateThread function. This type

 BOOL WINAPI (*)(HANDLE, DWORD). 

A HANDLE is defined as

typedef PVOID HANDLE;

So, the compiler wrote code to convert the "function pointer" type to PVOID, which is great for C ++ ($ 4.10 / 2)

"rvalue of type" pointer to cv T ", where T is the type of object, can be converted to rvalue of type" pointer to cv void. The result of converting the "pointer to cv T" to "Pointer to cv void" indicates the beginning of storage, where an object of type T is located as if the object is the most derived object (1.8) of type T (i.e., not a base class of a subobject).

EDIT 2:

@dreamlax is correct. It seems that in the C ++ 03 standard it is not allowed to convert a pointer to a void * function, as shown in the program below

 void f(){} int main(){ void (*p)(void) = f; void *p1 = p; } 

I wonder why.

+2
source share

The real answer: you're in luck. There are three types of code that you can pass to the C or C ++ compiler:

  • The correct code and behavior of which is determined by the standard or the compiler
  • Code that is completely incorrect to be rejected with an error
  • A code that is not correct enough to define behavior, but not error enough to be rejected.

This last category is “Undefined behavior” and is one of the worst things about C and C ++. The compiler will accept the code, but it most likely will not do what you wanted. Converting a function pointer to a void pointer is not what you wanted, and you probably want a compiler warning to tell you that you made a mistake.

Here is a list of possible undefined behavior in C ++. The best thing you can do is try to raise the warning level of your compiler. In Visual C ++, use /w3 or /w4 to raise the warning level and it will track undefined behavior at compile time. In gcc, use -ansi -pedantic -W -Wall to completely raise the warning level.

+1
source share

I assume that HANDLE is defined as void* , so any pointer (even a pointer to a function) can be marked implicitly on HANDLE

0
source share

All Articles