Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向成员的常量指针是否默认指向int?_C++_Syntax_Language Lawyer_Variable Declaration_Pointer To Member - Fatal编程技术网

C++ 指向成员的常量指针是否默认指向int?

C++ 指向成员的常量指针是否默认指向int?,c++,syntax,language-lawyer,variable-declaration,pointer-to-member,C++,Syntax,Language Lawyer,Variable Declaration,Pointer To Member,在使用指向成员的指针时,我遇到了一种行为,这种行为似乎有点不一致,对我来说有点违反直觉。考虑下面的虚拟结构: struct foo { int x; double d; }; 以及以下main(): 在这里,我们没有什么不寻常的地方——两个指向const成员的指针。代码编译得很好 引起我注意的是,当我们添加const时,情况会有一点变化。考虑下面的代码: int main() { // no int or double after const const foo

在使用指向成员的指针时,我遇到了一种行为,这种行为似乎有点不一致,对我来说有点违反直觉。考虑下面的虚拟结构:

struct foo {
    int x;
    double d;
};
以及以下
main()

在这里,我们没有什么不寻常的地方——两个指向
const
成员的指针。代码编译得很好

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

int main() {
    // no int or double after const
    const foo::* ptr = &foo::x;
}
代码在GCC 8.2.0上编译良好。请注意,我没有指定指针将指向的数据类型

但是,该代码:

int main() {
    // notice the only change - "d" instead of "x"
    const foo::* ptr = &foo::d;
}
未能编译,出现以下错误:

错误:无法在初始化中将“
double-foo::*
”转换为“
const-int-foo::*

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

值得注意的是,如果我们删除
常量
,这两行都会产生错误:

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

错误:在“
*
”标记之前应为非限定id

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

所以问题是-如果我们没有另外指定,标准是否指定
const
指向成员的指针隐式指向
int
,或者这是一种非标准行为?
(GCC扩展或GCC错误)


1EDIT:我正在使用来自MinGW的GCC-特定构建

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

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

错误:ISO C++禁止声明“没有类型”PTR 它不是一个扩展。允许在
-fpermissive
模式下使用,以保持非常旧的遗留代码可编译


但是,MinGW-w64提供的GCC似乎没有捕捉到这个错误。我不知道它是否有意。

< P>在ISO C++中代码是错误的,但是“隐式INT”行为是通过GCC自动启用针对微软ABI的。 您可以使用
-fno ms extensions
将其关闭


我检查了源代码(GCC-91.0/Gcc/CP/DELL.C),结果发现在MexExt>/Cuff>模式中,隐式INT的警告被禁用了——任何生成消息的代码> ISO C++禁止声明没有类型< /COD>的%QS,使用<代码> int <代码> >类型。

这可能比它试图解决的任何问题所需要的都要大。您还可以看到
const*x的差异
常数f()例如


我尝试将
-fno ms extensions
添加到我使用mingw-w64的一些“大型”Windows项目的构建中,但没有出现任何错误,因此,作为习惯,使用此标志可能是一种好的做法(或者甚至向mingw-w64提交一个补丁,默认情况下关闭它……。

“代码在GCC 8.2.0上编译得很好”呃,不,不是。您是使用
-fpemmissive
编译的吗?我强烈建议不要这样做。通常当没有给出类型时,会假定int。我想这就是为什么它对int有效,或者更确切地说是对double有效,但不是double。@Chipster我有没有提出其他建议?我不打算这么做。@Chipster啊,是的,我知道,但谢谢你。问题是我编译时没有
-fppermission
。它在godbolt上确实失败了,但在我的构建(我使用的是[here]-STL的构建中的MinGW),它仍然可以很好地编译,即使没有编译器标志。那么,你认为这是MinGW的一个bug吗?@Fureeish,你肯定应该把它包括在问题中。我可以在我的MinGW的GCC 8.1上复制它。@fureish它也发生在我自己在Linux上构建的MinGW GCC(8.3.0)交叉编译器上。似乎是一个一般性的mingw问题(或者更准确地说,mingw-w64)。@Fureeish在问题下的评论中说“它实际上使用
-fppermission
编译,没有它就不会编译”,但现在你说它不使用-fppermission编译;这是哪一个?@KeithThompson这似乎是意料之中的事。见M.M.的答案。我将发布我的Cygwin bug报告的后续内容。我很失望,在默认启用了
-fms扩展的系统上,
g++-std=c++11-pedantic
无法生成所需的诊断。我可能会向gcc提交一个bug。有趣的是,
gcc-fms extensions
警告C中的隐式
int
。您知道在默认情况下如何为MinGW和其他Windows版本打开该选项吗?这是一个配置选项,还是他们修改了gcc源代码?(我正在试图确定这是否是一个gcc错误。)@KeithThompson您可以通过在github上查找mingw-w64项目来检查源代码。好吧,他们根本没有修改gcc源代码,但他们显然在某个地方打开了这个选项。我不认为向gcc报告错误是有道理的,因为这似乎是预期的行为,但最好对
ms extensions
所做的事情进行更细粒度的控制(例如,如果他们允许
-Wimplicit int
否决
-fms扩展
。在建议更改之前,人们希望熟悉用例;我不是。可能有一些流行的代码库需要此标志。他们已经有一个过滤器,如果它被标识为系统头,则不会对此发出警告,可能是t不能正确识别windows标题?谁知道呢。@KeithThompson进一步检查后发现,标志控件在GCC源代码中;如果目标ABI是Microsoft的,它将启用它。
int main() {
    foo::* ptr1 = &foo::x;
    foo::* ptr2 = &foo::d;
}
error: ISO C++ forbids declaration of 'ptr' with no type