此代码标准是否符合?
#include <stdio.h>
#include <cstdio>
int main() {
FILE *f1 = 0;
std::FILE *f2 = f1;
}
说明:标准说[header]:
[...]每个标题
cname
的内容应与相应标题name.h
[...]的内容相同,就像包含一样。但是,在C ++标准库中,声明[...]位于命名空间std
的命名空间范围(3.3.6)内。 未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式 using-declarations (7.3.3)注入命名空间std
。
因此,如果它们没有通过显式使用声明注入,它们可能是不同的类型吗?我不认为“好像通过包含”这个词是决定性的,因为文本的另一半显然与这个要求相矛盾,要求名称在std
命名空间内。
答案 0 :(得分:3)
是的,这符合标准:FILE*
在stdio.h
,std::FILE*
cstdio
中宣布,由于您引用的段落,两者是相同的。
(唯一没有说明的是,如果你只包括<cstdio>
,你是否在全局命名空间中也有相同的FILE*
。)
更新:我认为的类型实际上与鼻子相同,并且每个类型只声明一次,然后通过using
声明注入另一个名称空间。唯一没有说明的是哪一个首先出现。相应的相反标准引用是D.5(2):
每个C头,每个头都有一个名称为name.h的行为,就好像每个由相应的cname头放在标准库命名空间中的名称放在全局命名空间范围内。未指定是否首先在名称空间std的名称空间作用域(3.3.6)中声明或定义这些名称,然后通过显式using-declarations(7.3.3)将这些名称注入到全局名称空间作用域。
基本上,这意味着两种实现是可能的:
“C首先出现”:
// foo.h
struct Gizmo { /* ... */ };
// cfoo
#include "foo.h"
namespace std { using ::Gizmo; }
“具有C兼容性的C ++:
// cfoo
namespace std
{
struct Gizmo { /* ... */ };
}
// foo.h
#include <cfoo>
using std::Gizmo;
答案 1 :(得分:2)
我不相信那段说它们必须是相同的。它只是对原始(C ++ 98)段落的修订,其中说:
每个C标头(每个标头都具有 name.h 形式的名称)就好像每个名称由相应的 cname 标头放置在标准库命名空间中一样也放在命名空间
std
的命名空间范围内,然后是显式 using-declaration (7.3.3)
这是难以理解的,因为它与大多数系统上现有的真正的 C标头冲突。因此,在C ++ 11中,文本被更改为您引用的文本。它允许以相反的方式实现它,就像它们在实践中一直做的那样 - 使用现有系统提供的C头并将名称导入名称空间std
。
但是,还有另一段说明无论执行方式如何,标题中的名称必须具有相同的含义:
对于标准C库中的每个类型
T
,类型::T
和std::T
都保留给实现,并且在定义时,::T
应与{相同} {1}}。 ([extern.types],17.6.4.3.4)
答案 2 :(得分:1)
是的,它们可以是不同的类型。使用C ++类型; C头只是为了兼容性。
考虑一下,如上面答案的评论所示,C ++标题是作为namespace std { #include "stdio.h" }
实现的;然后::FILE
和std::FILE
代表不同的类型。