`cname`和`name.h`中的类型可以是不同的类型?

这个代码标准是否符合?

#include <stdio.h>
#include <cstdio>

int main() {
    FILE *f1 = 0;
    std::FILE *f2 = f1;
}

说明:标准说[头]:

[...]每个标题cname的内容应与相应标题name.h [...]的内容相同,如同包含一样。 然而,在C ++标准库中,声明[...]在命名空间std的命名空间范围(3.3.6)内。 没有说明这些名称是否首先在全局命名空间范围内声明,然后通过显式使用声明(7.3.3)注入命名空间std

因此,如果它们没有通过明确的使用声明注入,它们可能是不同的类型? 我不认为“似乎通过包含”这个词组是确定性的,因为另一半的文本明显与这个要求矛盾,要求名称在std名称空间内。


我不相信那段说他们必须是相同的。 它只是对原始(C ++ 98)段落的修订,它说:

每个C头都有一个name.h形式的名称,就好像每个名称放在标准库名字空间中的相应的cname头一样,也放在名字空间std的名字空间范围内,并且后面跟着一个明确的using-声明(7.3.3)

这是困难的,不可能遵循的,因为它与大多数系统上现有的真正的C头相冲突。 因此,在C ++ 11中,文本被更改为您引用的那个。 它允许以其他方式实现它,就像他们在实践中一直做的一样 - 使用现有系统提供的C头文件并将名称导入到名称空间std

然而,还有另一段说,无论实现如何执行,标题中的名称都意味着同样的事情:

对于来自标准C库的每个类型T ,类型::Tstd::T保留给实现,并且在定义时, ::T应与std::T相同。 ([extern.types],17.6.4.3.4)


是的,这符合标准: FILE*stdio.h声明,在cstdio声明为std::FILE* ,并且由于您引用的段落,两者是相同的。

(唯一没有说明的是,如果你只包含<cstdio> ,你是否也在全局命名空间中具有相同的FILE* )。


更新:我相信这些类型在鼻子上实际上是相同的,并且每个类型只声明一次,然后通过using声明注入其他名称空间。 唯一没有说明的是哪个先来。 相应的相反标准报价是D.5(2):

每个C头都有一个名称为name.h的名称,就好像名称空间中由相应的cname头放置的每个名称放在全局名称空间范围内一样。 没有指定这些名称是首先在名称空间std的名称空间范围(3.3.6)中声明还是定义的,然后通过显式使用声明(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;

是的,他们可以是不同的类型。 使用C ++类型; C头文件仅用于兼容性。

考虑一下,如上面的答案的评论所表明的那样,C ++头文件被实现为namespace std { #include "stdio.h" } ; 那么::FILEstd::FILE将代表不同的类型。

链接地址: http://www.djcxy.com/p/29765.html

上一篇: Can types in `cname` and `name.h` be different types?

下一篇: cstdio stdio.h namespace