Jar*_*yth 35 c signed pointers return-value
我有一个函数,我希望能够返回失败和未初始化的特殊值(它返回成功指针).
目前它为失败返回NULL,为未初始化返回-1,这似乎有效......但我可能会欺骗系统.iirc,地址总是积极的,不是吗?(虽然由于编译器允许我将地址设置为-1,这看起来很奇怪).
[更新] 我有另一个想法(如果-1是有风险的)是malloc一个char @全局范围,并使用该地址作为哨兵.
caf*_*caf 71
不,地址并不总是正的 - 在x86_64上,指针是符号扩展的,地址空间对称地聚集在0左右(尽管通常"负"地址是内核地址).
然而,这一点大多没有实际意义,因为C只定义了指向同一个对象的一部分或一个超过数组末尾的指针之间的含义<
和>
指针比较.指向完全不同的对象的指针除了完全相等之外不能进行有意义的比较,至少在标准C if (p < NULL)
中没有明确定义的语义.
您应该创建一个具有静态存储持续时间的虚拟对象,并使用其地址作为您的unintialised
值:
extern char uninit_sentinel;
#define UNINITIALISED ((void *)&uninit_sentinel)
Run Code Online (Sandbox Code Playgroud)
它保证在您的程序中有一个唯一的地址.
Jam*_*lis 20
指针的有效值完全取决于实现,因此,是的,指针地址可能是负数.
但是,更重要的是,考虑(作为可能的实现选择的示例)您使用32位指针大小的32位平台的情况.可以由该32位值表示的任何值都可以是有效指针.除了空指针之外,任何指针值都可能是指向对象的有效指针.
对于您的特定用例,您应该考虑返回状态代码,并可能将指针作为函数的参数.
Jar*_*ger 17
尝试将特殊值复用到返回值上通常是一个糟糕的设计......你试图用单个值做太多.通过参数而不是返回值返回"成功指针"会更清晰.这会在您要描述的所有条件的返回值中留下大量非冲突空格:
int SomeFunction(SomeType **p)
{
*p = NULL;
if (/* check for uninitialized ... */)
return UNINITIALIZED;
if (/* check for failure ... */)
return FAILURE;
*p = yourValue;
return SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
您还应该进行典型的参数检查(确保'p'不是NULL).
C语言没有为指针定义"否定性"的概念."否定"的属性主要是算术的,不以任何方式适用于指针类型的值.
如果你有一个指针返回函数,那么你无法有意义地返回该-1
函数的值.在C语言中,积分值(除零之外)不能隐式转换为指针类型.尝试-1
从指针返回函数返回是立即约束违规,将导致诊断消息.简而言之,这是一个错误.如果您的编译器允许它,它只是意味着它不会过于严格地强制执行该约束(大多数时候它们是为了与预标准代码兼容).
如果-1
通过显式强制转换强制指针类型的值,则强制转换的结果将是实现定义的.语言本身并不能保证它.它可能很容易证明与其他一些有效的指针值相同.
如果要创建保留指针值,则无需malloc
任何操作.您可以简单地声明所需类型的全局变量,并使用其地址作为保留值.它保证是独一无二的.