为啥这段代码不能用 VS2010 和 gcc 4.8.1 编译

Posted

技术标签:

【中文标题】为啥这段代码不能用 VS2010 和 gcc 4.8.1 编译【英文标题】:Why this code isn't compile with VS2010 and gcc 4.8.1为什么这段代码不能用 VS2010 和 gcc 4.8.1 编译 【发布时间】:2014-03-17 17:50:09 【问题描述】:

简单,请看这段代码:

namespace B


    struct A int i;  ;

    A getA(int i);


//        ____ if I'll delete '::' then program successfull compiled.
//       /
::B::A  ::B::getA(int i) ::B::A a = i; return a;

#include <cstdio>
int main()


  ::B::A a = ::B::getA(2);

  printf("%d\n", a.i);


VS2010错误列表:

1>main.cpp(94): error C3083: 'B': the symbol to the left of a '::' must be a type
1>main.cpp(94): error C2039: 'getA' : is not a member of 'B::A'
1>main.cpp(88) : see declaration of 'B::A'
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>main.cpp(94): error C2440: 'return' : cannot convert from 'B::A' to 'int'
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>main.cpp(94): error C2617: 'getA' : inconsistent return statement
1>main.cpp(94) : see declaration of 'getA'

Gcc.4.8.1 错误列表(from ideone.com):

   prog.cpp:10:1: error: ‘B’ in ‘struct B::A’ does not name a type
 ::B::A  ::B::getA(int i) ::B::A a = i; return a;
 ^

问:这是一个错误还是我不明白什么?

【问题讨论】:

据我所知,“::”之前没有任何限定符意味着“在全局命名空间中找到它”。所以对于可能认为它是一个类的编译器来说,这是相当误导的。不知道为什么 @DavidKernin:因为前面的空格没有意义,所以附加到前面的A @MikeSeymour:我完全忽略了这一点。好眼力! 不知道,下次真的要记住了 【参考方案1】:

一般来说,标记之间的空格没有任何意义,除非在需要分隔标记的地方。所以这个:

::B::A  ::B::getA(...)

等价于

::B::A::B::getA(...)

要表示它们是两个单独的限定名称,请在函数名称周围使用括号:

::B::A (::B::getA)(...)

或者,正如您所说,删除***限定符(尽管如果您在范围内有其他称为 B 的东西,这可能会导致混淆)。

【讨论】:

【参考方案2】:

这是编译器看到的代码与您认为的不同的情况。这些异常难以调试,因为错误消息似乎无关紧要,几乎是随机的。

问题在于编译器忽略了::B::A::B::getA 之间的空格,所以它认为你在谈论函数::B::A::B::getA()。您不能定义该函数(在编译器的事物视图中没有返回类型)或调用该函数(基于稍后出现的函数体)并不重要。编译器没有足够的知识来解决歧义。相反,它意识到它从未见过::B::A::B 类型的声明,并给您一条错误消息。

【讨论】:

以上是关于为啥这段代码不能用 VS2010 和 gcc 4.8.1 编译的主要内容,如果未能解决你的问题,请参考以下文章

为啥这段代码不能在 Visual Studio 2010 中编译和运行?

为啥VS2013没有QT菜单 ??

为啥不继承 C++ 构造函数?

为啥我VS2008里的devexpress控件是灰色的不能拖,在VS2010里面却可以用?

vs2010使用vc++连接mysql数据库时,为啥我的数据库驱动也装了,但是还是不能选择mysql数据库

VSCode编写C++后不能编译运行