if ( test == ( void * ) -1 ) 中的“( void * ) ”是什么意思

What is the meaning of " ( void * ) " in : if ( test == ( void * ) -1 )

函数returns-1.

但是,下面代码中的(void*)是什么意思:

没有它还能工作吗?

test = shmat(shm_id, NULL, 0);

if (test == (void *)-1) {
    /* handle shmat failure */
}

shmat有如下原型:

void *shmat(int shmid, const void *shmaddr, int shmflg);

即它 return 是指向 void 的指针,而不是整数。

出错时它将 return 整数 -1 转换为指向 void 的指针。来自 Linux 联机帮助页 shmat(2):

On success, shmat() returns the address of the attached shared memory segment; on error, (void *) -1 is returned, and errno is set to indicate the cause of the error.

这就是您必须正确进行比较以检查错误return的方式。 C11 标准对 6.5.9p5-6 中的运算符 == 的描述如下:

5 Otherwise, at least one operand is a pointer. If one operand is a pointer and the other is a null pointer constant, the null pointer constant is converted to the type of the pointer.

If one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void, the former is converted to the type of the latter.

6 Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.109)

也就是说,标准定义了恰好 2 个转换的行为:一个操作数是指向 void 的指针,另一个操作数是指向其他对象的指针;或者一个操作数是指针,另一个操作数是空指针常量(即 0 或 (void*)0 等)。由于 -1 没有强制转换 既不是 空指针常量,也不是指针,标准没有为这种情况指定任何行为,因此行为是未定义的 "by the omission of any explicit definition".

test == -1 是错的,test == (void *) -1 是对的。

事实证明这仍然是一个灰色地带。 -1int 而在 my 计算机上,它是 32 位。整数到指针的转换由实现定义。 GCC manuals say:

A cast from pointer to integer discards most-significant bits if the pointer representation is larger than the integer type, sign-extends[2] if the pointer representation is smaller than the integer type, otherwise the bits are unchanged.

用脚注2说

Future versions of GCC may zero-extend, or use a target-defined ptr_extend pattern. Do not rely on sign extension.

因此这意味着 (void *)-1 也可能变得不正确;更安全的方法是将其写为 (void *)(intptr_t)-1.


出于某种原因,(void *)0,即空指针,未用于指示错误条件(即使在 C 中使用此类指针在标准方面是错误的)。

type casting.

函数shmat() returns a void*,所以类型转换用于将-1(int)转换为正确的类型(void* ).

实际上,是的,它可以工作,但你会从编译器那里得到一些警告。

切勿忽略可能隐藏错误的警告。