void* ptr = &func;使用 msvc 进行编译,无需任何诊断,但 gcc 和 clang 都拒绝它

问题描述 投票:0回答:1

我正在使用 Stanley 的《C++ Primer》一书学习 C++。特别是,关于“指针转换”的部分说:

指向任何非常量类型的指针都可以转换为

void*


读完本文后,我编写了以下程序,该程序使用 msvc 进行编译没有任何诊断,但被 gcc 和 clang 拒绝。 演示

int func()
{
    return 4;
}
int main()
{
    void* ptr = &func; //works with msvc but rejected by clang and gcc
}

如你所见看到上面的程序适用于msvc,但gcc说

error: invalid conversion from 'int (*)()' to 'void*'

我想知道哪个编译器是正确的。请注意,我已将

/permissive-
标志与 msvc 一起使用以使其符合标准。

c++ pointers language-lawyer function-pointers
1个回答
2
投票

该程序是格式错误,因为没有从指针到“函数类型”

void*
的隐式转换。仅当目标是 “对象类型”(而
int()
不是)时才允许隐式转换。这可以从 conv.ptr#2 中看出:

“指向 cv T 的指针”类型的纯右值,其中

T
是对象类型,可以转换为“指针”类型的纯右值 简历无效”。此转换不会改变指针值(6.8.3)

进一步来自 dcl.init#general

否则,正在初始化的对象的初始值是初始化表达式的(可能已转换)值。 标准转换序列 ([conv]) 用于将初始值设定项表达式转换为目标类型的 cv 未限定版本的纯右值;不考虑用户定义的转换。 如果无法完成转换,则初始化格式错误。 当使用无法表示的值初始化位字段时,位字段的结果值是实现定义的。

(强调我的)

请注意单词“对象类型”的强调。由于在您的代码中,

T=int()
是一个“函数类型”,因此没有从
int()
void*
的转换,这意味着程序格式不正确,并且msvc在接受程序时是错误的

© www.soinside.com 2019 - 2024. All rights reserved.