C 为什么VisualStudio2010中的ssize_t定义为未签名?

C 为什么VisualStudio2010中的ssize_t定义为未签名?,c,windows,types,C,Windows,Types,我有一个便携程序,它使用ssize_t,假设它是一个有符号整数。从概念上讲,它的作用类似于: #include <stdint.h> #include <stdio.h> int main(int argc, char *argv[]) { size_t size_10 = 10; size_t size_20 = 20; ssize_t len_diff; len_diff = (ssize_t)size_10 - (ssize_t)s

我有一个便携程序,它使用ssize_t,假设它是一个有符号整数。从概念上讲,它的作用类似于:

#include <stdint.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    size_t size_10 = 10;
    size_t size_20 = 20;
    ssize_t len_diff;
    len_diff = (ssize_t)size_10 - (ssize_t)size_20;
    if (len_diff < 0)
        printf("negative\n");
    else if (len_diff > 0)
        printf("positive\n");
    else
        printf("zero\n");
}
因此,减去两个无符号值将得到一个无符号值,从而得到结果

在旧版本的Windows SDK(如V7.0A)中,ssize_t被正确定义为:

//
// SIZE_T used for counts or ranges which need to span the range of
// of a pointer.  SSIZE_T is the signed variation.
//

typedef ULONG_PTR SIZE_T, *PSIZE_T;
typedef LONG_PTR SSIZE_T, *PSSIZE_T;
有人能解释这一变化吗?我们应该停止在Windows上使用ssize\t吗

更新: 根据所有的答案,它似乎是VisualStudio2010中的一个bug,其中包括ssize_t,但定义不正确。这是一只鬼鬼祟祟的臭虫

最近更新:
此错误已在VS2012和VS2016中修复。从评论讨论中还可以看出,当将比较的值转换为SSIZE_T

时,这种计算len_diff的方法似乎存在问题,尽管将
SSIZE_T
作为无符号整数肯定不符合POSIX标准,OP的代码也有可能破坏符合POSIX标准的系统

作为:

ssize\u t

用于字节计数或错误指示

[……]

类型ssize_t应能够存储至少在[-1,{ssize_MAX}范围内的值


ssize_t
而不是标准C,它是Posix中的一个typedef。您在VS2010的代码分析标题中找到它可能与源代码有关,大多数代码分析工具都是在Unix上启动的。它在VS2012及以后的版本中再次被删除

它出现在所有caps中的BaseTsd.h SDK文件中肯定不是错误,Windows支持Posix子系统。这些typedef将操作系统与编译器实现细节隔离开来,这是Windows能够在架构更改(从16位到32位再到64位)中幸存下来的基本原因


所以真正的问题是,您试图在Windows上编译Posix程序,但没有使用Posix头。解决这个问题很简单,只需在#includes之前添加您自己的typedef。

这是一个好的解决方案吗

#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
#如果已定义(_MSC_VER)
#包括
typedef SSIZE\u T SSIZE\T;
#恩迪夫

这是V7.0A中的一个错误。根据签名大小,t是长的。@EdS.:因此“或”。-)@R:……很公平。他们将签名版本的
size\u t
定义为unsigned,这真是太疯狂了。@EdS:在我看来,似乎所有的大写字母,MS style
SSIZE\u t
都是正确的,只是POSIX style
SSIZE\u t
被破坏了,因此,我怀疑这是另一次试图破解可移植跨平台代码并强制Windows特定的ifdef…@R的微妙尝试。。提到的
ssize\u t
buggy定义在VC2012Interest中不存在,因此它应该是
size\u t
,但保留了一个用于错误处理的值?我猜如果该值对于位数来说太大,-1用作溢流支架,errstr
size\u t
ssize\u t
只是打破了标准化,很难100%便携地混合,因为它们可能具有不同的正值范围。为了便于编写健壮的代码,@Mario是的,
ssize_t
的典型用例是返回值
read(2)
@alk是的,我想看看芯片设计师,他会开发一个基本标量类型的CPU,以匹配覆盖范围[-1]的ssize_t定义,{SSIZE_MAX}]。但是,您提出了一个有效的观点,即如果值与无符号量的一半值交叉,则代码会有问题。比较会在该半点上中断,例如,与铸造值1,10,-10,-1——这里我们将得到(1,10)=>负值,(10,-10)=>正值,这将是一个错误(在原始代码中)谢谢Hans,但是typedef出现在sourceannotations.h中,它用in/out/…宏注释所有API,因此默认情况下,它只包含stdint.h和stdio.h——所讨论的“posix”代码是LMDB()而且它是众多“可移植”库中的一个。如果他们费心定义ssize\t,为什么会以错误的方式显式定义它,这仍然是毫无意义的(正如正确定义的all caps版本所表明的那样)。这是另一个很好的解决方案。通常,它与
中的其他#定义(如果"智能感知"
)相结合。谢谢。
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif