【问题标题】:Alternative to ssize_t on POSIX-unconformant systems在不符合 POSIX 的系统上替代 ssize_t
【发布时间】:2016-04-07 10:26:55
【问题描述】:

我正在编写一个涉及网络 I/O 的程序,所以使用了 sendrecv,它们是 POSIX 函数。他们返回一个 ssize_t,这也是 POSIX 特定的。
包装器看起来像这样的 ATM:

ssize_t sock_send(int sock, const void* msg, size_t len) {
    return send(sock, msg, len, 0);
}

尽管我在当前的实现中严重依赖 POSIX,但我想让界面紧贴标准,因为我计划稍后编写一个 Windows 实现,而 POSIX 不一定可用(该死,Windows !)。

按照 C11 标准的规定,什么是 ssize_t 的良好替代品?也许ptrdiff_t
或者我应该如何处理这个问题?

【问题讨论】:

  • 为什么不给ssize_t 的typedef 加上昵称?
  • 只使用 ssize_t。如果您在没有它的平台上,请定义它
  • Using ssize_t vs int - 可能是骗局。

标签: c posix


【解决方案1】:

我发现上面有一个错字

#elif SIZE_MAX == UINTMAX_MAX
typedef uintmax_t ssize_t;  /* last resort, chux suggestion */
#define SSIZE_MIN  INTMAX_MIN
#define SSIZE_MAX  INTMAX_MAX

应该是

#elif SIZE_MAX == UINTMAX_MAX
typedef intmax_t ssize_t;  /* last resort, chux suggestion */
#define SSIZE_MIN  INTMAX_MIN
#define SSIZE_MAX  INTMAX_MAX

intmax_t(如果已定义)应该能够保存任何 signed 整数类型,这使其成为 ssize_t 的最后选择。

uintmax_t(如果已定义)应该能够保存任何 unsigned 整数类型。尝试将负数分配给无符号整数会导致回绕以使数字为正数,这在这里可能不希望出现。

【讨论】:

    【解决方案2】:

    如果类型ssize_t没有定义,你可以自己定义。它应该是与size_t 大小相同的signed 类型。从技术上讲,ptrdiff_t 类型不应小于size_t,但可以更大以适应更大的范围。

    这是一种可移植的方式来定义它:

    #include <limits.h>
    #include <stddef.h>
    #include <inttypes.h>
    #include <stdint.h>
    
    #if SIZE_MAX == UINT_MAX
    typedef int ssize_t;        /* common 32 bit case */
    #define SSIZE_MIN  INT_MIN
    #define SSIZE_MAX  INT_MAX
    #elif SIZE_MAX == ULONG_MAX
    typedef long ssize_t;       /* linux 64 bits */
    #define SSIZE_MIN  LONG_MIN
    #define SSIZE_MAX  LONG_MAX
    #elif SIZE_MAX == ULLONG_MAX
    typedef long long ssize_t;  /* windows 64 bits */
    #define SSIZE_MIN  LLONG_MIN
    #define SSIZE_MAX  LLONG_MAX
    #elif SIZE_MAX == USHRT_MAX
    typedef short ssize_t;      /* is this even possible? */
    #define SSIZE_MIN  SHRT_MIN
    #define SSIZE_MAX  SHRT_MAX
    #elif SIZE_MAX == UINTMAX_MAX
    typedef uintmax_t ssize_t;  /* last resort, chux suggestion */
    #define SSIZE_MIN  INTMAX_MIN
    #define SSIZE_MAX  INTMAX_MAX
    #else
    #error platform has exotic SIZE_MAX
    #endif
    

    【讨论】:

    • 我知道至少有一个平台会失败:在 MSP430X 微控制器上,一些工具链(尤其是最新版本的 gcc 工具链)使用 uint20_t 代表 size_tint20_t 代表 @987654330 @.
    • @FUZxxl:标准类型charshortintlonglong long有多少位?
    • @chrqlie 8、16、16、32、64。uintptr_tptrdiff_tintptr_tsize_tssize_t 都有 20 位。
    • @fuz uint20_t 和 8 位 char 看起来不合规,因为 uintN_tchar 不应该有填充并且位宽 20 不是位宽 8 的倍数. 嗯。
    • @chux-ReinstateMonica 真的,那个!他们应该叫它__uint20_t 或类似的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 2013-09-04
    • 2022-01-22
    相关资源
    最近更新 更多