在三元运算符中隐式转换为 void*?

tex*_*ral 5 c pointers conditional-operator language-lawyer implicit-conversion

我知道类型化指针void*在传递给需要void*参数的函数时可以隐式转换,但我没想到会在三元操作中看到它(至少我认为这是怎么回事)。

考虑这个简化的代码:

int * dude() {
    float * f = NULL;
    int * i = NULL;
    return (0 ? f : i);  // pointer type mismatch in conditional expression (good: this is what I want)
}
Run Code Online (Sandbox Code Playgroud)

但如果我投ivoid*

int * dude() {
    float * f = NULL;
    int * i = NULL;
    return (0 ? f : (void*)i);  // no error!  it suddenly likes f?  or is f being optimized out?
}
Run Code Online (Sandbox Code Playgroud)

我会更进一步,故意返回f

int * dude() {
    float * f = NULL;
    int * i = NULL;
    return (1 ? f : (void*)i);  // again no error... is f being converted to void*?
}
Run Code Online (Sandbox Code Playgroud)

我预计在第二个和第三个示例中都会出现错误,但我没有得到一个。有人可以解释这里发生了什么吗?谢谢!

int*_*jay 5

该标准明确表示,如果条件运算符的两个操作数都是指针,并且一个是void*(不包括空指针常量),则结果为void*。从 C11 6.5.15/6 开始:

如果第二个和第三个操作数都是指针,或者一个是空指针常量而另一个是指针,则结果类型是一个指向一个类型的指针,该类型由两个操作数引用的类型的所有类型限定符限定。此外,如果两个操作数都是指向兼容类型或兼容类型的不同限定版本的指针,则结果类型是指向复合类型的适当限定版本的指针;如果一个操作数是空指针常量,则结果具有另一个操作数的类型;否则,一个操作数是指向 void 或 void 的限定版本的指针,在这种情况下,结果类型是指向适当限定版本的 void 的指针。

  • @textral它们如何初始化并不重要 - 变量在任何情况下都不是空指针常量。要点是,将 `(void*)0` 直接放入条件语句中不会使条件语句具有 `void*` 结果类型。 (2认同)