我具有抽象用C实现的串行和套接字IO(Linux / Windows)的功能。所有这些都被标记为,extern "C"因为它们也可以从C ++中调用。
在这里使用__attribute__((__nothrow__))(或MinGW Macro __MINGW_NOTHROW)是否安全?我可以假设没有抛出异常吗?
调用的函数-套接字:(未列出WinSock的所有新增功能
)
socketconnectsend / recvclose(closesocket在Windows上)sendto / recvfrom所谓的函数-串行:
由于Windows / Linux之间的串行IO代码差异很大,因此此处未列出所有代码
opentcgetattrread / writecloseCreateFileGetCommState / SetCommTimeoutsReadFile / WriteFileCloseHandle由于ANSI C没有例外(如果我错了,请纠正我),它们不会被抛出,但是GCC扩展和OS API调用又如何呢?
文档:http : //gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html(请参阅参考资料nothrow)。
GNU C(Linux)使用__THROWmacro代替__MINGW_NOTHROW。MinGW一个__nothrow__仅是属性,也__THROW包含__leaf__属性。
如果使用C ++,则__THROW具有另一种含义:throw()-表示没有引发异常(类似于__nothrow__;,但在C ++标准中定义)。
因此,它取决于你是否编译 C或C ++,而不是你所说的从函数(GNU C /只,C ++! )。
例:
void f() __THROW;
Run Code Online (Sandbox Code Playgroud)
像...一样对待 ...
GNU C:
void f() __attribute__((__nothrow__, __leaf__))
Run Code Online (Sandbox Code Playgroud)
GNU C ++:
void f() throw()
Run Code Online (Sandbox Code Playgroud)
功能1)是取消点,因此未标记为
__THROW:
open()read()write()close()connect()send()recv()close()sendto()recvfrom()功能1) 标有__THROW:
tcgetattr()socket()至少将这些保存到__nothrow__。
相比之下,MinGW和C ++ 没有什么区别。在这两种情况下,都设置了属性。
使用上面的示例__nothrow__在C 和 C ++上进行设置:
void f() __attribute((__nothrow__))
Run Code Online (Sandbox Code Playgroud)
功能1) 没有标明有__MINGW_NOTHROW:
socket()connect()send()recv()closesocket()sendto()recvfrom()CreateFile()GetCommState()SetCommTimeouts()ReadFile()WriteFile()CloseHandle()简而言之:无!
兼容性
用C
期望与C ++互操作的C语言代码应使用-fexceptions进行编译。这将使得调试C语言功能成为可能,该功能称为C ++引发的堆栈展开的一部分。
特别是,展开到没有异常处理数据的帧中将导致运行时中止。如果展开器在找到处理程序之前耗尽了展开信息,则会调用std :: terminate()。
请注意,大多数开发环境应注意正确处理这些细节。对于GNU系统,已经使用-fexceptions编译了GNU C库的所有适当部分。
(来源:http : //gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html)
因此,使用进行编译,-fexceptions不需要等效属性。如果您只能标记特定功能,则必须/应该使用__nothrow__。
但是,尽管使用__nothrow__属性外观仅在GNU C ++上保存,而在Linux上保存GNU C的某些功能,但在Windows上不清楚。
为避免此问题的某些部分,我编写了与__THROWMinGW 相似但也可用的宏:
#if defined __GNUC__
#ifndef __THROW
#ifdef __cplusplus
#define __THROW throw()
#else
#define __THROW __attribute__((__nothrow__))
#endif
#endif
#else
#define __THROW
#endif
Run Code Online (Sandbox Code Playgroud)
注意: __leaf__不包括在内。
1) 只谈论我的问题中列出的那些。