gpt4 book ai didi

c - 两次将指针转换为 `void*` 怎么会无效?

转载 作者:太空宇宙 更新时间:2023-11-04 01:19:39 25 4
gpt4 key购买 nike

关于 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

最佳答案

你问的是一个人为的例子,意在说明 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 的整数常量表达式,可能将 one 转换为 void *它的前面。任何额外的转换,它不再是一个空指针常量(但仍然是一个常量表达式)。 (整数常量表达式不能包含指向指针类型的内部转换。)

在你的对比例子中

int a;
int *pa = (int *)&a;

不涉及空指针,也没有整型常量表达式,并且转换确实是 100% 冗余的。 &a 可以是一个常量表达式(当且仅当 a 具有静态存储持续时间),但它不是一个整数常量表达式。

关于c - 两次将指针转换为 `void*` 怎么会无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47446430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com