代码之家  ›  专栏  ›  技术社区  ›  Lior Kogan

为什么这段代码要编译?

  •  7
  • Lior Kogan  · 技术社区  · 14 年前

    ::TerminateThread(::TerminateThread, 0);
    

    因为TerminateThread()定义为

    BOOL WINAPI TerminateThread(HANDLE hThread, DWORD dwExitCode);
    

    我不知道为什么我能编译它。

    有什么解释吗?

    4 回复  |  直到 14 年前
        1
  •  7
  •   dreamlax    14 年前

    HANDLE 是指向void的指针,Microsoft的编译器允许隐式地将函数指针转换为指向void的指针。

    这让我犯了很多次错误,尤其是堆函数:

    HeapAlloc (GetProcessHeap, 0, size); // oops, should be GetProcessHeap()
    
        2
  •  2
  •   Chubsdad    14 年前

    它接受函数的地址 ::TerminateThread

    BOOL WINAPI (*)(HANDLE, DWORD).
    

    typedef PVOID手柄;

    “指向cv T的指针类型的右值, 其中T是对象类型,可以是 指向cv void的指针。结果 存储位置的起始位置 T类型的对象驻留在 对象是最派生的对象 类子对象)

    编辑2:

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

    我想知道为什么。

        3
  •  1
  •   Community kfsone    7 年前

    • 完全错误的代码将被错误拒绝
    • 没有正确到足以定义行为,但没有错误到足以被拒绝的代码。

    这是一份 possible undefined behaviour in C++. 你能做的最好的事情就是试着提高编译器的警告级别。在Visual C++中的使用 /w3 /w4 -ansi -pedantic -W -Wall 把你的警告级别调高到满。

        4
  •  0
  •   Niki    14 年前

    我猜 HANDLE void* ,因此任何指针(甚至函数指针)都可以隐式地转换为 手柄