反对使用 size_t 的理由是什么?

发布于 2024-12-06 19:28:25 字数 445 浏览 4 评论 0 原文

我有一个这样的 API,

class IoType {
......
    StatusType writeBytes(......, size_t& bytesWritten);
    StatusType writeObjects(......, size_t& objsWritten);
};

我尊敬的团队中的一位高级成员似乎对 size_t 类型有问题,并建议我使用 C99 类型。我知道这听起来很愚蠢,但我总是认为像 uint32_t 和 uint64_t 这样的 c99 类型看起来很难看。我确实使用它们,但只有在确实有必要时才使用它们,例如当我需要序列化/反序列化结构时,我确实想具体说明数据成员的大小。

反对使用 size_t 的理由是什么?我知道它不是真正的类型,但如果我确定,即使 32 位整数对我来说也足够了,并且大小类型似乎适合字节数或对象数等。

I have a API like this,

class IoType {
......
    StatusType writeBytes(......, size_t& bytesWritten);
    StatusType writeObjects(......, size_t& objsWritten);
};

A senior member of the team who I respect seems to have a problem with the type size_t and suggest that I use C99 types. I know it sounds stupid but I always think c99 types like uint32_t and uint64_t look ugly. I do use them but only when it's really necessary, for instance when I need to serialize/deserialize a structure, I do want to be specific about the sizes of my data members.

What are the arguments against using size_t? I know it's not a real type but if I know for sure even a 32-bit integer is enough for me and a size type seems to be appropriate for number of bytes or number of objects, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余厌 2024-12-13 19:28:25

每当您处理任何类型的序列化(二进制文件、网络等)时,请使用精确大小的类型,例如 uint32_t。每当您处理内存中对象的大小时,请使用 size_t — 这就是它的用途。所有处理对象大小的函数,例如 mallocstrlensizeof 运算符都是 size_t

如果正确使用 size_t,您的程序将具有最大程度的可移植性,并且不会在不需要的平台上浪费时间和内存。在 32 位平台上,size_t 将是 32 位 - 如果您使用 uint64_t,则会浪费时间和空间。相反,在 64 位平台上,size_t 将是 64 位 - 如果您使用 uint32_t,您的程序可能会行为不正确(甚至可能崩溃或打开安全性)漏洞)如果它必须处理大于 4 GB 的内存。

Use exact-size types like uint32_t whenever you're dealing with serialization of any sort (binary files, networking, etc.). Use size_t whenever you're dealing with the size of an object in memory—that's what it's intended for. All of the functions that deal with object sizes, like malloc, strlen, and the sizeof operator all size_t.

If you use size_t correctly, your program will be maximally portable, and it will not waste time and memory on platforms where it doesn't need to. On 32-bit platforms, a size_t will be 32 bits—if you instead used a uint64_t, you'd waste time and space. Conversely, on 64-bit platforms, a size_t will be 64 bits—if you instead used a uint32_t, your program could behave incorrectly (maybe even crash or open up a security vulnerability) if it ever had to deal with a piece of memory larger than 4 GB.

想挽留 2024-12-13 19:28:25

我认为在不需要序列化值的上下文中使用 size_t 有什么问题。正确使用 size_t 还将提高代码在 32 位和 64 位模式下的安全性/可移植性。

I can't think of anything wrong in using size_t in contexts where you don't need to serialize values. Also using size_t correctly will increase the code's safety/portability across 32 and 64 bit patforms.

红焚 2024-12-13 19:28:25

嗯,用可移植性较差的 C99 固定大小或最小大小无符号类型替换 size_t (最大可移植性的东西)并不是一个好主意。

另一方面,您可以通过使用有符号的 ptrdiff_t 类型来避免很多技术问题(浪费时间)。标准库使用无符号类型只是出于历史原因。它在当时是有意义的,甚至在今天的 16 位架构上也是有意义的,但通常它只是麻烦和麻烦。冗长。

不过,做出这一改变需要一些支持,特别是通用的 size 函数,返回数组或容器大小为 ptrdiff_t


Now, regarding your function signature

    StatusType writeBytes(......, size_t& bytesWritten);

强制调用代码选择写入字节数的类型。

然后,强制使用无符号类型size_t,很容易引入错误,例如通过检查它是否小于或大于某个计算量。

一个奇怪的例子:std::string("ah").length() std::string("ah").length() -5 保证为true

因此,请这样做……

    Size writeBytes(......);

或者,如果您不想使用异常,

    Size writeBytes(......, StatusType& status );

可以将可能的状态枚举为无符号类型或其他类型,因为对状态值的唯一操作将是相等检查,并且可能作为键。

Uhm, it's not a good idea to replace size_t (a maximally portable thing) with a less portable C99 fixed size or minimum size unsigned type.

On the other hand, you can avoid a lot of technical problems (wasted time) by using the signed ptrdiff_t type instead. The standard library’s use of unsigned type is just for historical reasons. It made sense in its day, and even today on 16-bit architectures, but generally it is nothing but trouble & verbosity.

Making that change requires some support, though, in particular a general size function that returns array or container size as ptrdiff_t.


Now, regarding your function signature

    StatusType writeBytes(......, size_t& bytesWritten);

This forces the calling code’s choice of type for the bytes written count.

And then, with unsigned type size_t forced, it is easy to introduce a bug, e.g. by checking if that is less or more than some computed quantity.

A grotesque example: std::string("ah").length() < -5 is guaranteed true.

So instead, make that …

    Size writeBytes(......);

or, if you do not want to use exceptions,

    Size writeBytes(......, StatusType& status );

It is OK to have an enumeration of possible statuses as unsigned type or as whatever, because the only operations on status values will be equality checking and possibly as keys.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文