SIG_ERR上的C++旧式强制转换警告

C++ old-style cast warning on SIG_ERR

本文关键字:转换 警告 ERR 上的 C++ SIG      更新时间:2023-10-16

在使用带有-Wold-style-cast标志的g++ (gcc version 4.2.1 20070719)(具体为OpenBSD 5.6(编译一些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上给我一个警告?

警告不是因为您的代码,而是在定义SIG_ERR<signal.h>中。我现在没有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>,您会发现类似的东西。