将指针比较为-1

时间:2011-11-30 22:23:40

标签: c pointers

我有一个相当哲学的问题,验证shmat函数输出。 这样做:

void * addr = shmat(shmid, NULL, 0);
if( addr == -1)
{
    perror("Uncool stuff");
}

给了我:

warning: comparison between pointer and integer

这是完全可以的。不幸的是,手册说:

Upon success, shmat() returns the address where the segment is attached; 
otherwise, -1 is returned and errno is set to indicate the error.

这是非常标准的行为,但我应该如何处理呢? if (addr == (void *) -1)是否正确?我已经阅读了this question,现在我不确定,如果它在每个可能的平台上都是100%正确的 - 等等等等等等;-)我还没有找到任何关于此事的其他可靠消息来源。

我相信,询问指针的签名是一个错误,因为指针不是数字。但在这种情况下,我不再确定......

修改:此问题引出了另一个问题:char *addr = (char*)shmat(...)是否正确?根据答案到目前为止,它是,但如果我们考虑没有mmu等等...是的,也许我在这里失去与现实的联系,但我很好奇是否有 THE 正确的方式。

3 个答案:

答案 0 :(得分:4)

documentation明确指出shmat在出错时返回(void*)-1,因此您应该将结果与之比较。您可能正在查看较旧版本的文档。这有点像黑客攻击,但它应该适用于任何符合POSIX标准的系统(它做出了C标准无法保证的假设)。将返回的指针转换为整数类型然后与-1进行比较可能会也可能不会起作用;例如,请考虑intvoid*可能有不同的尺寸。

如果没有先检查返回的值,请不要尝试检查errno。通常,函数可以将errno设置为某个非零值,即使它们成功。始终检查返回的值以检测故障,然后您可以检查errno以确定故障类型。如果您要检查errno,请务必在通话前将其设置为0。 (在这种情况下,我不确定这是绝对必要的,但这是一种很好的做法。)

答案 1 :(得分:1)

是的,这是正确的,但很难看。

要让它返回-1,它必须进行相同类型的转换,因此它应该适用于大多数平台。

答案 2 :(得分:1)

IMO此测试几乎适用于所有情况 if (addr == (void*)-1 ...

如果你真的想回避这个问题,那就去做吧 #include <errno.h> ... errno = 0; void * addr = shmat(shmid, NULL, 0); if (errno != 0) ... IOW使用errno来检测错误,而不是来自shmat的返回值。

(我的单元测试中有一个案例用于我的假设;在新平台上运行它们可以帮助您检测由该平台上的意外行为引起的错误。)