c - 关于 `size_t`和它们测量的指针类型

标签 c pointers types typedef

size_t 未定义时,据说获取其定义的唯一可移植方法是包含其中一个包含它的 header 。

但是,据我所知,在头文件中使用 #include 是不好的做法,因为头不应该包含其他头,对吧?

因此,程序员有责任找到一种方法来确保 header 能够编译,而不会陷入糟糕的编程实践。

据我了解,size_t 类型是保证支持您的系统可以处理的最长对象的最小类型。例如。如果您运行 64 位操作系统,则 size_t 应该是 64 位,因为这就是 RAM 和指针本身的工作方式。

至于指针,任何给定的指针都表示从 RAM 中的第 0 个字节开始的偏移量,取消引用该偏移量将为您提供存储在该偏移量处的值。并且 CPU(在本例中为 64 位)被赋予完全控制权来访问它能够使用它支持的最大单元(即 64 位整数)寻址的任何 18 quintillion 左右的字节,又名指针。

因此,不是 size_t 和任何给定的指针类型保证大小相同吗?

那么,问题是以下哪一项是给定 header 的最佳实践:

void some_function(ptr *some_object, size_t n);
...

可能性似乎是:

#include <stddef.h>
// would definitely work...but including a header in a header is ugly practice

typedef long long unsigned size_t
// to account for win64 making `long` 32-bits...but it's possibly non-portable

typedef char * size_t
// I like this one...but am not 100% sure about how portable it is

此外,是否有任何理由不希望使用指针来定义 size_t?好像应该没问题。据我了解,指针保证占用寄存器的全部大小,因此应该与体系结构的“理想”大小相同 size_t

最佳答案

When size_t is undefined, it's said that the only portable way to get the definition for it is to include one of the headers that has it.

正确。

However, as I understand it, using an #include in a header file is bad practice, because headers shouldn't include other headers, right?

你被误导了。没有理由不在其他 header 中包含 header 。多个 #include相同 header 的 s 可能会导致问题如果它们没有适当的包含守卫,但标准 header 保证有这样的守卫(或等效)——非标准 header 应该 有这样的守卫。 (<assert.h> 是一个特例。)

如果需要size_t , 在源文件或头文件中,那么你应该使用 #include <stddef.h>起名字size_t可见(或者您可以包含其他标准 header 之一,这些 header 也使 size_t 可见)。

包括<stddef.h>在 header 中将使它的声明在包含您的 header 的任何其他文件中可见,但这不是问题。

As I understand it, the size_t type is the smallest type guaranteed to support the longest object your system can handle.

它是由实现选择的无符号整数类型来保存大小值。它应该能够保存任何对象的字节大小(尽管没有明确保证)。不能保证它是最小的此类类型,并且假设它是这样也没有任何好处。

As for pointers, any given pointer represents an offset from the 0th byte in RAM, where dereferencing that offset will give you the value stored at that offset.
[...]
Thus, aren't size_t and any given pointer type guaranteed to be the same size?

不,没有这样的保证。在大多数现代系统中,指针确实表示从虚拟 地址 0 开始的字节偏移量,但这并不能保证。在具有分段内存模型的系统上,单个对象的最大大小可能远小于内存大小;一个指针可能包含一个段指示符和一个字节偏移量,一个对象不允许占用超过一个段。

size_t 类型的值需要能够表示任何单个对象的大小。指针(例如 void*unsigned char* 类型)需要能够表示任何对象或其中任何字节的地址。

不要对指针或 size_t 的大小做出任何不必要的假设.让编译器为您解决。

The possibilities seem to be:

#include <stddef.h>
// would definitely work...but including a header in a header is ugly practice

不,这不是丑陋的做法。就这样做吧。

typedef long long unsigned size_t
// to account for win64 making `long` 32-bits...but it's possibly non-portable

这绝对是不可移植的。 size_t 甚至有可能可能比 unsigned long long 宽.但是定义你自己的类型比编译器的 size_t 更宽既无用也无必要。如果您稍后添加 #include,它会产生冲突。对于正确定义size_t的几个标准 header 之一(或对于包含这些 header 之一的任何 header )。

typedef char * size_t
// I like this one...but am not 100% sure about how portable it is

绝对不是。 size_t必须是无符号整数类型。如果有人告诉您整数和指针可以互换,那您就被严重误导了。

关于c - 关于 `size_t`和它们测量的指针类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38817577/

相关文章:

c - 使用指向 const 的指针

c - 来自不兼容指针类型 C 的许多赋值

c - 向客户端发送 100,000 个 UDP 数据包(C Socket 编程)

c - 指向结构的指针在 C 中返回不正确的值

r - R 中的预测和 glm.predict 错误

haskell - 我如何 "Extract"Haskell中某个角度的值

c - Ruby C 扩展,如何从段错误中恢复

c - 带有头文件和椅子的 3 维数组

c++ - 为指向类对象的指针重载 operator<

java - 字符串无法转换为字符,如何解决?