串行/套接字IO和GCC nothrow属性

oll*_*llo 1 c io gcc mingw

我具有抽象用C实现的串行套接字IO(Linux / Windows)的功能。所有这些都被标记为,extern "C"因为它们也可以从C ++中调用。

在这里使用__attribute__((__nothrow__))(或MinGW Macro __MINGW_NOTHROW)是否安全?我可以假设没有抛出异常吗?

调用的函数-套接字:(未列出WinSock的所有新增功能

  • socket
  • connect
  • send / recv
  • closeclosesocket在Windows上)
  • sendto / recvfrom

所谓的函数-串行:
由于Windows / Linux之间的串行IO代码差异很大,因此此处未列出所有代码

  • Linux(GNU)
    • open
    • tcgetattr
    • read / write
    • close
  • Windows(MinGW)
    • CreateFile
    • GetCommState / SetCommTimeouts
    • ReadFile / WriteFile
    • CloseHandle

由于ANSI C没有例外(如果我错了,请纠正我),它们不会被抛出,但是GCC扩展和OS API调用又如何呢?

文档:http : //gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html(请参阅参考资料nothrow)。

oll*_*llo 5

C

GNU C(Linux)使用__THROWmacro代替__MINGW_NOTHROW。MinGW一个__nothrow__仅是属性,也__THROW包含__leaf__属性。

C ++

如果使用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) 只谈论我的问题中列出的那些。