警告(不合时宜):将 void(*)(int) 分配给 extern "C" void(*)(int)
Warning (Anachronism): Assigning void(*)(int) to extern "C" void(*)(int)
我在使用Sun的c++编译器时遇到了麻烦。我读过Oracle的《使用指针指向函数》[来自c++]。这是一个很好的阅读,我得到的印象是SunCC是这个领域所有编译器中最兼容的(尽管它给我带来了麻烦)。
测试代码如下,第24行是new_handler.sa_handler = (pfn ? pfn : &SignalHandler::NullHandler);
。展开三元运算符显示出问题所在:new_handler.sa_handler = pfn;
.
SunCC 5.11
$ /opt/solstudio12.2/bin/CC test.cxx
"test.cxx", line 24: Warning (Anachronism): Assigning void(*)(int) to extern "C" void(*)(int).
"test.cxx", line 58: Where: While instantiating "SignalHandler<5, 0>::SignalHandler(void(*)(int), int)".
"test.cxx", line 58: Where: Instantiated from non-template code.
SunCC 5.12
$ /opt/solarisstudio12.3/bin/CC test.cxx
"test.cxx", line 24: Warning (Anachronism): Assigning void(*)(int) to extern "C" void(*)(int).
"test.cxx", line 58: Where: While instantiating "SignalHandler<5, 0>::SignalHandler(void(*)(int), int)".
"test.cxx", line 58: Where: Instantiated from non-template code.
SunCC 5.13
$ /opt/solarisstudio12.4/bin/CC test.cxx
"test.cxx", line 24: Warning (Anachronism): Using void(*)(int) to initialize extern "C" void(*)(int).
"test.cxx", line 58: Where: While instantiating "SignalHandler<5, 0>::SignalHandler(void(*)(int), int)".
"test.cxx", line 58: Where: Instantiated from non-template code.
SunCC 5.14
$ /opt/developerstudio12.5/bin/CC test.cxx
$
我不太清楚问题出在哪里。这里有一个类似的问题在Oracle板,但OP基本上是告诉RTFM: Sun Studio 11"警告(时代错误)"。
如何解决时间错误警告?
solaris:~$ cat test.cxx
#include <signal.h>
extern "C" {
typedef void (*SignalHandlerFn) (int);
};
template <int S, bool O=false>
struct SignalHandler
{
SignalHandler(SignalHandlerFn pfn = NULL, int flags = 0) : m_installed(false)
{
struct sigaction new_handler;
do
{
int ret = 0;
ret = sigaction (S, 0, &m_old);
if (ret != 0) break; // Failed
if (m_old.sa_handler != 0 && !O) break;
new_handler.sa_handler = (pfn ? pfn : &SignalHandler::NullHandler);
new_handler.sa_flags = (pfn ? flags : 0);
ret = sigemptyset (&new_handler.sa_mask);
if (ret != 0) break; // Failed
ret = sigaction (S, &new_handler, 0);
if (ret != 0) break; // Failed
m_installed = true;
} while(0);
}
~SignalHandler()
{
if (m_installed)
sigaction (S, &m_old, 0);
}
private:
struct sigaction m_old;
bool m_installed;
static void NullHandler(int /*unused*/) { /* continue*/ }
private:
// Not copyable
SignalHandler(const SignalHandler &);
void operator=(const SignalHandler &);
};
int main(int argc, char* argv[])
{
SignalHandler<SIGTRAP, 0> handler;
return 0;
}
您可以将SignalHandler::NullHandler更改为普通的C函数(我们将其命名为SignalHandler_NullHandler)。然后将SignalHandler_NullHandler和SignalHandlerFn都包装在extern " C "中。
顺便说一句。这是我的猜测如何"对齐"这两个函数,但你在评论中更好地解释了C/c++类型转换的问题。
表达式中:
pfn ? pfn : &SignalHandler::NullHandler
第二个和第三个操作数具有不同的类型(因为一个指向具有"C"语言链接的函数,一个指向具有"c++"语言链接的函数);并且没有改变语言链接的隐式转换。
所以表达式是病态的。另一种解决方法建议使用强制类型转换,但这可能会以在运行时无声的未定义行为为代价来抑制诊断:通过指向不同类型函数的指针调用函数。
当然,特定的编译器可能提供扩展来定义c++标准未定义的任何场景中的行为。(或者碰巧"不管怎样都能工作")。
我的建议是将SignalHandler::NullHandler
替换为具有C语言链接的函数。这不能是类成员,因为语言语法排除了extern "C"
出现在类定义中。
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 不能使这种类型的"void(C::* volatile)(int) const "在参考手册C++示
- 如何使模板函数像 R f<void(int)>(args...)
- template<class T, int N> void h(T const(&)[N]); as friend function
- 函数 LNK2019 "int __cdecl __scrt_common_main_seh(void)" 中引用的未解析外部符号主错误 (?__scrt_common_main_seh@@YAHXZ
- 从不兼容的类型 'void (Button::*)(int)' 分配给'void (*)(int)'
- 错误 C2084:函数"int main(void)"已具有主体
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- int main(void) 在 C++ 中有效吗?
- sqlite3 更改函数回调参数 void* not用于 int* C++
- 什么是 qsort void*x 和 *(int*)x?
- 无法将参数 1 从"int (__thiscall A::* *)(void)"转换为"int (__cdecl *)(void)"
- 需要获取 void 或 int 的 Cpp 模板函子
- 为什么我可以将 void* static_cast 到 int* 而不是 int*&?
- 您如何通过函数的void指针将int值传递,然后将其转换回int值
- x = malloc(n * sizeof (int));无法将 void 转换为 int
- 错误:从"int (*)(std::list<myclass*>, int, char**, char**)"到"int (*)(void*, int, char**, char**)"的
- 如何在c++中将数组char复制到字符串或int*(void*)中