关于zwol's answer,我很困惑为什么
typedef void (*fp)(void); // any pointer-to-function type will show this effect fp c = (void *)(void *)0; // invalid conversion in both C and C++
最后一行怎么办无效?对我来说,这听起来像将int(0)
转换为void*
两次,将指针转换为相同类型应该绝对正常,如下所示:
int a, *pa = (int*)&a;
// ^^^^^^ Totally OK
答案 0 :(得分:4)
你问的问题是一个人为的例子,用来说明C规则的一个极端情况,而无效的东西不是双重演员,而是分配。
如果您有任何指针到函数类型,例如
typedef void (*fp)(void);
您可以使用任何有效的空指针常量初始化此类型的变量,例如
fp a = 0; // canonical null pointer constant in C
fp b = (void *)0; // another common choice
fp c = '\0'; // yes, really, this is a null pointer constant
fp d = (1-1); // and so is this
但你不能使用指向fp
本身以外的任何特定类型的指针来初始化它们,即使该指针是空指针,即使有问题的特定类型是void *
。
char *x = 0;
void *y = 0;
fp e = x; // invalid: no assignment conversion from `char *` to `fp`
fp f = y; // invalid: no assignment conversion from `void *` to `fp`
我老回答的那句话让你感到困惑,
fp g = (void *)(void *)0;
与上面的fp f = y
基本相同。两个赋值的右侧是类型为void *
的空指针,但不空指针常量,因此赋值无效。
您可能现在想知道为什么(void *)(void *)0
不是空指针常量,即使(void *)0
是空指针常量。这就是C标准恰好被写入的方式:空指针常量被定义为值为0的任何整数常量表达式,可能在其前面有一个强制转换为void *
。任何额外的强制转换,它不再是空指针常量(但仍然是一个常量表达式)。 (整数常量表达式不能包含指针类型的内部强制转换。)
在你的对比例中
int a;
int *pa = (int *)&a;
不涉及空指针,也没有整数常量表达式,并且强制转换实际上是100%冗余。 &a
可以是常量表达式(当且仅当a
具有静态存储持续时间时),但它不是整数常量表达式。