我的简单代码如下:
a.cpp:
#include <iostream>
namespace asd
{
class B
{
public:
void ss()
{
extern int i;
std::cout << i;
}
};
}
int main()
{
asd::B e;
e.ss();
}
b.cpp:
int i = 4;
此代码是标准还是不合适? Visual Studio编译它没有错误,但英特尔C ++编译器说: 未解决的外部符号&#34; int asd :: i&#34; (?我@ @@ ASD 3HA)
如果我将b.cpp改为:
,那就更有趣了namespace asd
{
int i = 4;
}
然后Visual Studio C ++ 2013说: 未解决的外部符号&#34; int i&#34; (?我@@ 3HA)
但是英特尔C ++编译器说好了:) 这段代码的正确版本是什么如果我想在类成员函数中使用这个extern(这是合法的吗?)?
编辑: 当我们将b.cpp改为:
时,最好的结果是namespace asd
{
int i = 4;
}
int i = 5;
Visual c ++ print 5,intel compiler 4:)
答案 0 :(得分:3)
在任何函数中声明extern
或static
变量是合法的。您对b.cpp
定义extern
所定义的asd
的修正也是正确的解决方法。
Visual Studio C ++ 2013在i
命名空间之外抱怨名称(请查看demangler以查看名称i
周围的这些额外字符代表什么)。这是不正确的,因为声明会将asd
放入命名空间extern
。
C ++标准在3.5.7节中说明了这一点。它使用namespace X {
void p() {
q(); // error: q not yet declared
extern void q(); // q is a member of namespace X
}
void middle() {
q(); // error: q not yet declared
}
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q
函数作为示例,但它说明了名称在封闭名称空间中的放置规则。
extern
第4,9和11行的注释表明,在成员函数中用{{1}}声明的名称需要放在封闭的命名空间中。这是一个很好的,独立的测试用例,说明了Microsoft编译器中的一个错误。
答案 1 :(得分:2)
看起来Visual Studio是错误的。
这是我在标准草案中找到的:
3.3.2 / 10
块作用域中的函数声明和块作用域中
extern
说明符的变量声明是指作为封闭命名空间成员的声明,但它们不会在该作用域中引入新名称。
话虽如此,我会将extern
声明移出函数并进入命名空间,看看是否有任何区别。
namespace asd
{
extern int i;
class B
{
public:
void ss()
{
std::cout << i;
}
};
}