8

有人可以解释以下内容:

$ cat test.cpp 
#include <string>
std::string div;
$ g++ -c test.cpp 
$ g++ -std=c++11 -c test.cpp 
test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol
In file included from /usr/include/c++/4.7.1/cstdlib:66:0,
                 from /usr/include/c++/4.7.1/ext/string_conversions.h:37,
                 from /usr/include/c++/4.7.1/bits/basic_string.h:2814,
                 from /usr/include/c++/4.7.1/string:54,
                 from test.cpp:1:
/usr/include/stdlib.h:787:14: error: previous declaration of 'div_t div(int, int)'
$

对于 C++11 模式,div符号不应该也在命名空间中吗?std还是我的系统特有的东西?

4

3 回答 3

4

/usr/include/stdlib.h

C stdlib 标头中的每个名称都.h驻留在全局命名空间中(显然)。

此外,任何C++ stdlib 标头都将在命名空间中cHEADER定义相应的名称,但也允许将它们放在全局命名空间中(所以他们可以这样做HEADER.hstd

// cHEADER
#include <HEADER.h>

namespace std{
using ::one_name_from_HEADER;
using ::another_name_from_HEADER;
// and so on...
}

并完成它)。

§D.5 [depr.c.headers]

p2 每个 C 标头,每个都有一个名为 form 的名称,其name.h行为就好像每个由相应cname标头放置在标准库命名空间中的名称都放置在全局命名空间范围内一样。未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式使用声明 (7.3.3) 注入全局命名空间范围。

p3 [示例:标头<cstdlib>确实在命名空间 std 中提供了它的声明和定义。它还可以在全局命名空间中提供这些名称。头文件<stdlib.h>在全局命名空间中确实提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间 std 中提供这些名称。—结束示例]

如您所见,反过来也是如此 (<HEADER.h>可能会在命名空间中引入名称std,就好像

// HEADER.h
#include <cHEADER>

using std::one_name_from_HEADER;
using std::another_name_from_HEADER;
// and so on...
}

),这使得这些标头之间的整个区别相当...无用,真的。

于 2012-10-23T22:25:30.383 回答
3

div是来自 的函数<stdlib.h>

在 C++11 中,<cblah>头文件被允许在全局命名空间中放置东西。

C++11 §17.6.1.2/4
“除了第 18 到 30 条和附件 D 中的说明外,每个头文件的内容应与C 标准库 (1.2) 中规定的相应头文件的内容相同或 C Unicode TR,视情况而定,就好像通过包含一样。然而,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在 namespace 的命名空间范围 (3.3.6) 内。未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式using 声明(7.3.3)注入命名空间 std 。”cnamename.hstd

反映常见 C++ 实现的现实。

因此,除了正式的情况外,实际上没有任何改变:您看到的行为现在受到标准的认可,而不是成为必须考虑的实现工件。

此外,正式的更改更容易争论 SO 应该更好地包含.h标头而不是cxxx标头......

于 2012-10-23T22:21:50.067 回答
1

17.6.4.3.3/1 规定:

在标头中声明为具有外部链接的对象的每个名称都保留给实现以指定具有外部链接的库对象,在名称空间和全局名称空间中均为182 。std

div是在头文件 cstdlib 中声明为具有外部链接的函数的名称,因此是全局命名空间中的保留名称。你不能使用这个名字。

于 2012-10-23T22:54:02.387 回答