在开源组件中,cjson,
#define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L)
上面的语句用于检查指针的有效性,如下所示
json_object* reply = json_object_new_object();
if (!reply || is_error(reply))
{
. . . //error handling
}
如何比较指针与(unsigned long)-4000L
验证指针?
答案 0 :(得分:4)
原因似乎是他们使用指针值来包含“指针或错误值”。
struct json_object* json_tokener_parse(const char *str)
{
struct json_tokener* tok;
struct json_object* obj;
tok = json_tokener_new();
obj = json_tokener_parse_ex(tok, str, -1);
if(tok->err != json_tokener_success)
obj = error_ptr(-tok->err); // <<<<<---
json_tokener_free(tok);
return obj;
}
该函数返回一个特殊值作为指针。 err_ptr
macro返回错误代码的否定,可能是因为作者认为这永远不会是有效的指针地址。
Here is a test演示宏的预期用法,即格式错误的JSON。
new_obj = json_tokener_parse("{ foo }");
if(is_error(new_obj)) printf("got error as expected\n");
因此,使用该特殊值的原因是它们可以保存“指向结构的指针或错误代码”。这也可以通过联合或结构或其他方式完成,但他们选择这样做。
答案 1 :(得分:0)
看起来像作者正在针对虚拟内存的分配位置做出特定于平台的假设。在这种情况下,假设有效指针总是位于可寻址空间的前4GB内 [编辑:long
是32位的(可疑的)假设。
您的特定示例似乎来自一个名为OpenWebOS的东西。我不知道那是什么;但如果他们是操作系统的制造者,那么他们就可以自己制定关于指针将去哪里的规则。也许该操作系统甚至有一个约定高于某个值的约定用于发出错误信号。
如果你想编写可移植代码,你应该在尝试这样的技巧之前先思考。
答案 2 :(得分:0)
除了一些非常特殊的情况之外,它没有 - 也许原作者有一个指针错误,指针被破坏的方式是他们进入&#34;范围&#34;这个比较,或者他的编译器和操作系统有一些奇怪的非标准指针验证或解释&#34;功能&#34;。
-4000被解释为无符号的32位整数是0xfffff060。
如果它是在内核中运行的代码,它 mighy 与userland /内核内存空间分隔有关(即上半部分与地址空间的下半部分),但即便如此可能是错的。我的钱是第一个想法。
答案 3 :(得分:0)