在size_t和unsigned int之间划清界限
Where to draw the line between size_t and unsigned int?
我目前正在将我多年来一直在开发的代码库中的unsigned int
的一些用途转换为size_t
。我理解两者之间的区别,例如unsigned int
可以是32位,而指针和size_t
可以是64位。我的问题更多的是关于我应该在什么地方使用它们,以及人们在两者之间选择时使用什么样的约定。
很明显,内存分配应该采用size_t
而不是unsigned int
作为参数,或者容器类应该像STL一样使用size_t
作为大小和索引。这些是在阅读size_t
和unsigned int
的好处时提到的常见案例。然而,在进行代码库转换时,我偶然发现了一些灰色地带的情况,我不确定该使用哪一种。例如,如果4x4矩阵行/列索引应该使用size_t
来保持一致性,而不管索引在[0,3]范围内,或者如果屏幕/纹理分辨率应该使用size_t
,尽管在几千的范围内,或者一般来说,如果合理的对象数量预计在几十的范围内,我仍然应该使用size_t
来保持一致性。
在unsigned int
和size_t
之间选择使用什么样的编码约定?是否所有表示大小(以字节或对象为单位)或索引的内容都应该始终为size_t
,而不管合理预期的范围如何?是否有一些被广泛接受的size_t
惯例在完善的库中使用,我可以遵循?
我认为这很简单,尽管我欢迎你用弹弓和箭。
size_t
应该用来描述有大小的东西。(一个计数。A number of things)
我最近考虑到一些遗留代码的32到64位端口,我认为size_t的关键特征是它总是足够大,可以表示整个地址空间。
您可以命名的任何其他类型(包括unsigned long)都有可能在将来某个时候人为地限制您的数据结构。当您无法在域上定义硬先验上界时,Size_t(及其同类ptrdiff_t)应该作为数据结构构造的默认基础。
对我来说,问题是你是否使用小于架构宽度的整数,问题是你是否可以证明更小的尺寸是足够的。
以你的4x4矩阵为例:是否有一个理论上的原因,为什么必须是4x4,而不是5x5或8x8?如果有这样一个理论上的原因,我对较小的整数类型没有问题。如果没有,则使用size_t
或其他至少具有相同宽度的类型。
我的理由是固定的限制(固定的整数大小只是引入这些限制的一种方式)通常是沉睡的bug。某一天,某人可能会发现一些极端的用例,在这些用例中,您为确定限制所做的假设并不成立。所以无论它们在哪里出现,你都要避开它们。由于我通常不会为更小的大小做证明(因为这对性能没有意义),因此我通常最终使用完整大小的整数。
- int x 和 int x=0 之间的差异在C++
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 使用模板在size_t和int之间进行隐式类型转换
- 在 ENG US 和 ENG INT 之间切换时,GetKeyboardLayout() 不会改变
- 使用 double 在 C++ 中初始化 int 之间的差异
- C :使用函数过载与CHAR到INT之间的隐式转换,反之亦然
- 为什么字符串和 int 之间的 + 运算符充当 substr
- int f(int *i) 和 int f(int &i) 之间的区别
- "new int[5]"和"malloc(5 * sizeof(int))"之间的C++有什么区别?
- 在“有符号的 int”和“无符号的 int”之间进行添加
- 一个关于C++中double和int之间转换的奇怪结果
- 向量 <int> V[] 和向量<向量<int> > V 之间的区别
- map< "string" ,..> 和 map<int,..> 之间的性能差异?
- int p = *(int *)i 和 int p = *(int *)&i 之间的区别
- int x{} 之间有区别吗?和整数 x = 0;
- int[n][n] 和 int** 之间的关系
- C++字符和 int 之间的转换,结果错误
- void(int) 和 void (*)(int) 之间的区别
- int someInts[3]和int*someInts=new int[3]之间的差异