2015-07-05 37 views
0

使用g++ (gcc version 4.2.1 20070719)(具體OpenBSD 5.6來編譯)一些C++代碼與-Wold-style-cast標誌,我遇到了一些老式的轉換警告,對於某些我不確定的信號處理程序代碼演員陣容正在發生。SIG_ERR上的C++舊式強制轉換警告

MCVE:

// compile with g++ file.cpp -Wold-style-cast 
#include <iostream> 
#include <csignal> 

typedef void (*sighndlr)(int); 

void sig_handler(int sig) 
{ 
    std::cout << "got sig: " << sig << std::endl; 
} 

int main(int argc, char* argv[]) 
{ 
    // warning: use of old-style cast 
    sighndlr sh = SIG_ERR; 

    // warning: use of old-style cast 
    void (*sigerr1)(int) = SIG_ERR; 

    // warning: use of old-style cast 
    void (*sigerr2)(int) = static_cast<void(*)(int)>(SIG_ERR); 

    // warning: use of old-style cast 
    void (*sigerr3)(int) = reinterpret_cast<void(*)(int)>(SIG_ERR); 

    // warning: use of old-style cast 
    if (std::signal(SIGABRT, sig_handler) == SIG_ERR) { 
     std::cout << "error install SIGABRT" << std::endl; 
    } 

    // no errors or warnings 
    if (std::signal(SIGTERM, sig_handler) == sigerr1) { 
     std::cout << "error install SIGTERM" << std::endl; 
    } 
    // no errors or warnings 
    std::signal(SIGSEGV, sig_handler); 

    // This was just to confirm SIG_ERR wasn't some weird definition 
    // error: invalid conversion from 'void (*)(int)' to 'void* (*)(int)' 
    // void* (*e0)(int) = SIG_ERR; 
    return 0; 
} 

警告沒有引起任何問題,我想通了void (*sigerr2)(int) = static_cast<void(*)(int)>(SIG_ERR)它是在過於謹慎分析錯誤的-Wold-style-cast標誌的一部分,但我更好奇,爲什麼它會給我std::signal(SIGABRT, sig_handler) == SIG_ERR上的警告,而不是std::signal(SIGTERM, sig_handler) == sigerr1

回答

1

該警告不是因爲您的代碼,而是<signal.h>,其中SIG_ERR已定義。我沒有一個Linux發行版,現在來檢查,但快速谷歌發現這一點:

#if defined(_ANSI_SOURCE) || defined(__cplusplus) 
#define SIG_DFL  (void (*)(int))0 
#define SIG_IGN  (void (*)(int))1 
#define SIG_ERR  (void (*)(int))-1 
#else 
#define SIG_DFL  (void (*)())0 
#define SIG_IGN  (void (*)())1 
#define SIG_ERR  (void (*)())-1 
#endif 

這顯然是實現定義的,但我敢肯定,如果你用grep你<signal.h>你會發現類似的東西。

+1

作爲一個方面說明,我堅信不應該使用此警告。 「老」風格演員沒有什麼不對,只有程序員不能閱讀代碼。 – Blindy

+0

就是這樣!在我跳躍之前應該已經grep'd ..我認爲你和BSD的工作人員可能會相處:從我的發行版中的'signal.h'正上方'SIG_ERR'的唯一定義之上,等等。 '語言規範說我們必須準確地列出一個參數,儘管我們實際上提供了三個參數。唉!' – txtechhelp