我有抽象serial- 和socket IO (Linux/Windows) 用C 实现的函数。
它们都被标记为 extern "C"
,因为它们也可能被 C++ 调用。
在这里使用 __attribute__((__nothrow__))
(或 MinGW 宏 __MINGW_NOTHROW
)是否安全/我可以假设没有抛出异常吗?
调用函数 - 套接字:
(未列出所有针对 WinSock 的添加)
套接字
连接
发送
/接收
close
(closesocket
在 Windows 上)发送到
/recvfrom
调用函数 - 序列号:
由于串行 IO 代码在 windows/linux 之间差异很大,因此此处并未列出所有代码
- Linux (GNU)
打开
tcgetattr
读取
/写入
关闭
- Windows (MinGW)
创建文件
GetCommState
/SetCommTimeouts
ReadFile
/WriteFile
关闭句柄
因为 ANSI C 没有异常(如果我错了请纠正我)它们不会被抛出,但是 GCC 扩展和 OS API 调用呢?
文档:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (参见 nothrow
)。
最佳答案
C
GNU C (Linux) 使用 __THROW
宏代替 __MINGW_NOTHROW
。
MinGW 只有 __nothrow__
属性,而 __THROW
也包含 __leaf__
属性。
C++
如果你使用C++,__THROW
还有另外一个意思:throw()
——表示没有异常被抛出(类似于__nothrow__
;但是在 C++ 标准中定义)。
所以这取决于您是用 C 还是 C++ 编译,而不是您调用函数的来源(仅限 GNU C/C++!)。
示例:
void f() __THROW;
被视为...
GNU C:
void f() __attribute__((__nothrow__, __leaf__))
GNU C++:
void f() throw()
函数1)是取消点,因此未标记
__抛出
:
open()
读取()
write()
关闭()
connect()
发送()
recv()
关闭()
sendto()
recvfrom()
函数1) 用__THROW
标记:
tcgetattr()
套接字()
至少,这些都保存到__nothrow__
。
相比之下,MinGW 没有区别 C 和 C++;在这两种情况下都设置了属性。
使用上面的示例,__nothrow__
在 C 和 C++ 上设置:
void f() __attribute((__nothrow__))
函数1)未标记__MINGW_NOTHROW
:
套接字()
connect()
发送()
recv()
closesocket()
sendto()
recvfrom()
创建文件()
GetCommState()
SetCommTimeouts()
ReadFile()
WriteFile()
CloseHandle()
简而言之:没有!
Compatibility
With C
C language code that is expecting to interoperate with C++ should be compiled with -fexceptions. This will make debugging a C language function called as part of C++-induced stack unwinding possible.
In particular, unwinding into a frame with no exception handling data will cause a runtime abort. If the unwinder runs out of unwind info before it finds a handler, std::terminate() is called.
Please note that most development environments should take care of getting these details right. For GNU systems, all appropriate parts of the GNU C library are already compiled with -fexceptions.
(来源:http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html)
因此使用 -fexceptions
进行编译并且不需要等效属性。如果您只能标记特定功能,则必须/应该使用 __nothrow__
。
但是使用 __nothrow__
属性看起来只在 GNU C++ 上保存,而在 Linux 上使用 GNU C 的一些功能,在 Windows 上就不是那么清楚了。
附录:
为了避免这个问题的某些部分,我写了一个类似于 __THROW
但也可以在 MinGW 上使用的宏:
#if defined __GNUC__
#ifndef __THROW
#ifdef __cplusplus
#define __THROW throw()
#else
#define __THROW __attribute__((__nothrow__))
#endif
#endif
#else
#define __THROW
#endif
注意: __leaf__
不包括在内。
1) 只谈论我的问题中列出的那些。
关于c - Serial-/Socket IO 和 GCC nothrow 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13690584/