当 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/