应该使用 size_t 或 ssize_t [重复]

Posted

技术标签:

【中文标题】应该使用 size_t 或 ssize_t [重复]【英文标题】:should use size_t or ssize_t [duplicate] 【发布时间】:2013-03-22 07:03:27 【问题描述】:

在我的代码中,我不使用 int 或 unsigned int。我只将 size_t 或 ssize_t 用于便携式。例如:

typedef size_t intc;    // (instead of unsigned int)
typedef ssize_t uintc;  // (instead of int)

因为strlenstringvector……都用size_t,所以我一般用size_t。而且我只在ssize_t 可能为负数时使用。

但我发现:

无符号整数类型非常适合将存储视为位数组的用途。 使用 unsigned 而不是 int 来获得更多位来表示正整数几乎不是一个好主意。 通过声明变量 unsigned 来确保某些值是正数的尝试通常会被隐式转换规则所挫败。

在书中The C++ Programming Language。

所以我很困惑。我错了吗?为什么 STL 不遵守书上的建议?

【问题讨论】:

size_t 在标准库中用于表示尺寸。如果容器的大小可能是负数,那就太奇怪了。接口说明它的行为。我认为这本书假设日常使用,而不是界面 @kassak - 不,在这种情况下,无符号类型实际上 is 用于获取该值的一个额外位。委员会的一些成员认为能够拥有大于一半可用内存的std::vector<char> 非常重要。并且引用说“几乎从不”...... 提名重新打开,因为引用的重复内容没有足够接近这篇文章。 intc 用于unsigned size_t(正如你所说,'[signed] int' 在评论中,即使它可能更长),以及@987654334 @ for signed ssize_t(评论中的'unsigned int')让我感到困惑,因为通常 'u' 代表 unsigned,例如uint32_tint32_t无符号 版本,一个 4 字节整数。 致那些标记为重复的人。这绝对不是重复的。问题不在于有符号与无符号,而在于 size_t 与 ssize_t,即“我什么时候应该使用其中一个”? 【参考方案1】:

ssize_t 用于返回值可以是有效大小或表示错误的负值的函数。 保证至少能够在[-1, SSIZE_MAX] 范围内存储值(SSIZE_MAX 取决于系统)。

因此,当您要返回以字节为单位的大小时,您应该使用size_t,而当您要返回以字节为单位的大小或(负)错误值时,您应该使用ssize_t

见: http://pubs.opengroup.org/onlinepubs/007908775/xsh/systypes.h.html

【讨论】:

好吧,这个答案未能完全解释基于纯界面考虑做出此类决定的后果。任何实现都不太可能为ssize_t 使用比size_t 更宽的类型。这立即意味着您为能够返回负值所付出的代价是该类型正值范围的减半。 IE。 SSIZE_MAX 通常是 SIZE_MAX / 2。应牢记这一点。在许多情况下,仅仅为了能够将-1 作为负值返回,这个代价是不值得的。 @AnT 具有无符号值是 C++ 中最大的失败之一。没有不值得付出代价的情况。如果您需要如此大的数字,请改用 int64_t... @thesaint 你到底在说什么?这与容量无关。如果堆栈指针的当前值可能是负数,也可能不是负数,你将如何向堆栈指针添加四? 无符号整数不是出现在 first (在有符号整数之前),因为硬件 - 显然这比大多数 C++ 使用更接近裸机 C,但使用MSB 允许有符号算术不仅仅是为了将“整数”可以表示的绝对大小减半,而是因为需要减法数学。有符号整数和无符号整数是梨和苹果 - 不同但能够在某些有限的情况下交叉......! (每个范围的一半是共享的。 对我来说,混淆的地方似乎是当一个函数似乎只应该产生一个无符号值,即read(2) 能够实际读取的字节数。然而,在发生错误的情况下,返回值 -1(可能编码为所有位集) - 不是为了让事情变得困难,而是因为它是一个无法正常出现的 sentinel 值。【参考方案2】:

ssize_t 不包含在标准中,并且不可移植。在处理对象的大小时应该使用size_t(还有ptrdiff_t,用于指针差异)。

【讨论】:

ssize_t 来自 POSIX:pubs.opengroup.org/onlinepubs/009696799/basedefs/sys/… C++11 及更高版本实现了模板std::make_signed,但如果使用size_t 作为其参数定义明确,则有点灰色区域。在 c++20 中,使用此模板和标准不允许的类型会导致格式错误的代码,但现有实现允许使用 size_t

以上是关于应该使用 size_t 或 ssize_t [重复]的主要内容,如果未能解决你的问题,请参考以下文章

<cstdint> 与 std::size_t 类型

用于 RPC 的 XDR 中的 ssize_t 数据类型

c size_t

C++,最佳实践,int 还是 size_t? [复制]

索引数组时我应该总是使用 size_t 吗?

使用read write 读写socket