我注意到现代的C和C++代码似乎size_t代替int/ unsigned int几乎无处不在 - 从C字符串函数的参数到STL.我很好奇这个原因及其带来的好处.
我看到用这种类型定义的变量,但我不知道它来自何处,也不知道它的目的是什么.为什么不使用int或unsigned int?(其他"类似"类型呢?Void_t等).
我正在尝试将现有代码调整为64位机器.主要问题是在一个函数中,前一个编码器使用void*参数,该参数在函数本身中转换为合适的类型.一个简短的例子:
void function(MESSAGE_ID id, void* param)
{
if(id == FOO) {
int real_param = (int)param;
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
当然,在64位机器上,我收到错误:
error: cast from 'void*' to 'int' loses precision
Run Code Online (Sandbox Code Playgroud)
我想纠正这个问题,以便它仍然可以在32位机器上运行并且尽可能干净.任何的想法 ?
我知道它是一个整数类型,可以在不丢失数据的情况下强制转换为指针,但为什么我要这样做呢?使用整数类型有什么优势void*可以保存指针和THE_REAL_TYPE*指针算术?
编辑
标记为"已被询问"的问题没有回答这个问题.问题是如果使用intptr_t作为一般的替换void*是一个好主意,那里的答案似乎是"不要使用intptr_t",所以我的问题仍然有效:什么是一个很好的用例intptr_t?
情况如下:
现在在64位机器上,哪个语句是正确的(如果有的话):
假设由于溢出,带符号的二进制整数11111111001101100000101011001000只是负数.这是一个实际存在的问题,因为您可能希望分配比在32位整数中描述的更多的字节.但后来它被读入64位整数.
Malloc将其读取为64位整数,发现11111111001101100000101011001000#################################是一个通配符位,表示在原始整数之后存储的任何数据.换句话说,它读取接近其最大值2 ^ 64的结果并尝试分配一些quintillion字节.它失败.Malloc将其读取为64位整数,转换为0000000000000000000000000000000011111111001101100000101011001000,可能是因为它是如何加载到寄存器中而使大量位为零.它不会失败,但会分配负内存,就像读取正无符号值一样.Malloc读取它为64位整数,转换为################################11111111001101100000101011001000,可能是因为它是如何加载到寄存器中的#一个表示寄存器中先前数据的通配符.根据最后一个值,它无法完全失败.我实际测试了这个,导致malloc失败(这意味着1或3是正确的).我认为1是最合乎逻辑的答案.我也知道修复(使用size_t作为输入而不是int).
我真的想知道究竟发生了什么.出于某种原因,我没有找到任何关于如何在64位机器上实际处理32位整数以进行这种意外"演员"的澄清.我甚至不确定它在寄存器中是否真的很重要.
或者它可以是一个单独的无符号整数类型?
我对不同的(无符号)整数类型有不同的模板函数特化.我需要提供单独的专业size_t吗?
我一直在批评使用uint而不是使用size_t,但每次检查我正在使用的工具链时,结果都size_t被定义为uint.
是否有任何编译器实现size_t实际上不是uint?批评的理由是什么?