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
是对的。
事实证明这仍然是一个灰色地带。 -1
是 int
而在 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 中使用此类指针在标准方面是错误的)。
函数shmat()
returns a void*
,所以类型转换用于将-1(int
)转换为正确的类型(void*
).
实际上,是的,它可以工作,但你会从编译器那里得到一些警告。
切勿忽略可能隐藏错误的警告。
函数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, anderrno
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
是对的。
事实证明这仍然是一个灰色地带。 -1
是 int
而在 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 中使用此类指针在标准方面是错误的)。
函数shmat()
returns a void*
,所以类型转换用于将-1(int
)转换为正确的类型(void*
).
实际上,是的,它可以工作,但你会从编译器那里得到一些警告。
切勿忽略可能隐藏错误的警告。