指向成员的const指针默认指向一个int吗?

时间:2019-06-10 00:26:41

标签: c++ syntax language-lawyer variable-declaration pointer-to-member

在使用指向成员的指针的过程中,我遇到了一种行为,这种行为似乎与我有些矛盾,有些违反直觉。考虑以下虚拟结构:

struct foo {
    int x;
    double d;
};

和以下main()

int main() {
    int foo::* ptr = &foo::x;
    double foo::* ptr2 = &foo::d;
}

在这里,我们没有任何异常-两个指向const成员的指针。该代码可以很好地编译。

引起我注意的是,当我们添加const时,情况有所变化。考虑以下代码:

int main() {
    // no int or double after const
    const foo::* ptr = &foo::x;
}

代码在 GCC 8.2.0 1 上可以正常编译。注意,我没有指定指针指向的数据类型。

但是,此代码:

int main() {
    // notice the only change - "d" instead of "x"
    const foo::* ptr = &foo::d;
}

无法编译,并出现以下错误:

  

错误:初始化double foo::*时无法将'const int foo::*'转换为'const foo::* ptr = &foo::d;'

这很有趣-它暗示默认情况下,const指向成员的指针被隐式声明为指向某个int成员。这是正确的标准行为吗?

值得注意的是,如果我们放下const,这两行都会产生错误:

int main() {
    foo::* ptr1 = &foo::x;
    foo::* ptr2 = &foo::d;
}

采用以下形式:

  

错误:“ *”令牌之前存在预期的不合格ID

     

错误:'ptr1'|未在此范围内声明“ ptr2

所以问题是-如果没有另外指定,标准是否指定const指向成员的指针隐式指向int,还是非标准行为? (GCC扩展程序或GCC错误)。


1 编辑:我正在使用MinGW的GCC-this特定版本。

2 个答案:

答案 0 :(得分:2)

该代码在ISO C ++中不正确,但是-fms-extensions启用了“隐式int”行为,gcc会自动启用该行为以定位Microsoft ABI。

您可以使用-fno-ms-extensions将其关闭。


我检查了源代码(gcc-9.1.0 / gcc / cp / decl.c),结果发现在ms-extensions模式下,隐式int 的警告已禁用- -实际上会产生任何可能生成消息ISO C++ forbids declaration of %qs with no type的任何内容,其中int被用作类型。

这可能比解决它要解决的任何问题所需的锤子更大。例如,您还可以查看与const *x;const f();的差异。

我尝试将-fno-ms-extensions添加到我使用mingw-w64的一些“大型” Windows项目的构建中,并且没有出现错误,因此将这个标志作为问题可能是一个好习惯习惯(甚至向mingw-w64提交补丁以默认关闭它)。

答案 1 :(得分:1)

  

所以问题是-如果我们不另外指定,标准是否指定const指向成员的指针隐式指向int

不。 GCC通常会以简单的英语给出答案,并且拒绝编译(如果使用-fpermissive,则发出警告):

error: ISO C++ forbids declaration of 'ptr' with no type

它不是扩展名。允许在-fpermissive模式下使用,以使非常旧的旧代码可编译。

MinGW-w64随附的GCC似乎没有捕获此错误。我不知道这是否是故意的。