const 指向成员的指针是否默认指向一个 int?
Does const pointer-to-member default to pointing to an int?
在玩指向成员的指针时,我遇到了一种似乎有点不一致并且对我来说有点违反直觉的行为。考虑以下虚拟结构:
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.01 上编译良好。请注意,我没有指定指针指向的数据类型。
然而,这段代码:
int main() {
// notice the only change - "d" instead of "x"
const foo::* ptr = &foo::d;
}
编译失败,出现以下错误:
error: cannot convert 'double foo::*
' to 'const int foo::*
' in initialization const foo::* ptr = &foo::d;
这很有趣 - 它表明,默认情况下,const
指向成员的指针被隐式声明为指向某个 int
成员。这是正确的标准行为吗?
值得注意的是,如果我们删除 const
,这两行都会产生错误:
int main() {
foo::* ptr1 = &foo::x;
foo::* ptr2 = &foo::d;
}
形式为:
error: expected unqualified-id before '*
' token
error: 'ptr1
' | 'ptr2
' was not declared in this scope
所以问题是 - 如果我们不另外指定,标准是否指定 const
指向成员的指针隐式指向 int
,或者它是非-标准行为?(GCC 扩展或 GCC 错误)。
1编辑:我正在使用 MinGW 的 GCC - this 特定版本。
So the question is - does the standard specify that const pointer-to-member implicitly points to int if we do not specify otherwise
没有。 GCC 通常会用简单的英语给你答案并拒绝编译(如果你使用 -fpermissive
则发出警告):
error: ISO C++ forbids declaration of 'ptr' with no type
这不是扩展。在 -fpermissive
模式下允许这样做,以保持非常旧的遗留代码的可编译性。
似乎 MinGW-w64 发布的 GCC 没有捕捉到这个错误。不知道是不是故意的
ISO C++ 中的代码不正确,但 "implicit int" 行为由 启用,gcc 自动启用以针对 Microsoft ABI。
您可以使用 -fno-ms-extensions
将其关闭。
我查看了源代码(gcc-9.1.0/gcc/cp/decl.c),结果发现在ms-extensions
模式下,implicit int[=31的警告=] 被禁用 - 任何会生成消息 ISO C++ forbids declaration of %qs with no type
的东西实际上都被允许,int
被用于该类型。
这可能是一个比解决它试图解决的任何问题所必需的更大的锤子。例如,您还可以看到与 const *x;
或 const f();
的差异。
我尝试将 -fno-ms-extensions
添加到我使用 mingw-w64 的一些 "large" Windows 项目的构建中并且没有出现错误,所以也许它会很好练习将此标志作为习惯问题(或者甚至向 mingw-w64 提交补丁以默认关闭它...)。
在玩指向成员的指针时,我遇到了一种似乎有点不一致并且对我来说有点违反直觉的行为。考虑以下虚拟结构:
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.01 上编译良好。请注意,我没有指定指针指向的数据类型。
然而,这段代码:
int main() {
// notice the only change - "d" instead of "x"
const foo::* ptr = &foo::d;
}
编译失败,出现以下错误:
error: cannot convert '
double foo::*
' to 'const int foo::*
' in initializationconst foo::* ptr = &foo::d;
这很有趣 - 它表明,默认情况下,const
指向成员的指针被隐式声明为指向某个 int
成员。这是正确的标准行为吗?
值得注意的是,如果我们删除 const
,这两行都会产生错误:
int main() {
foo::* ptr1 = &foo::x;
foo::* ptr2 = &foo::d;
}
形式为:
error: expected unqualified-id before '
*
' tokenerror: '
ptr1
' | 'ptr2
' was not declared in this scope
所以问题是 - 如果我们不另外指定,标准是否指定 const
指向成员的指针隐式指向 int
,或者它是非-标准行为?(GCC 扩展或 GCC 错误)。
1编辑:我正在使用 MinGW 的 GCC - this 特定版本。
So the question is - does the standard specify that const pointer-to-member implicitly points to int if we do not specify otherwise
没有。 GCC 通常会用简单的英语给你答案并拒绝编译(如果你使用 -fpermissive
则发出警告):
error: ISO C++ forbids declaration of 'ptr' with no type
这不是扩展。在 -fpermissive
模式下允许这样做,以保持非常旧的遗留代码的可编译性。
似乎 MinGW-w64 发布的 GCC 没有捕捉到这个错误。不知道是不是故意的
ISO C++ 中的代码不正确,但 "implicit int" 行为由
您可以使用 -fno-ms-extensions
将其关闭。
我查看了源代码(gcc-9.1.0/gcc/cp/decl.c),结果发现在ms-extensions
模式下,implicit int[=31的警告=] 被禁用 - 任何会生成消息 ISO C++ forbids declaration of %qs with no type
的东西实际上都被允许,int
被用于该类型。
这可能是一个比解决它试图解决的任何问题所必需的更大的锤子。例如,您还可以看到与 const *x;
或 const f();
的差异。
我尝试将 -fno-ms-extensions
添加到我使用 mingw-w64 的一些 "large" Windows 项目的构建中并且没有出现错误,所以也许它会很好练习将此标志作为习惯问题(或者甚至向 mingw-w64 提交补丁以默认关闭它...)。