【问题标题】:Why does the implicit declaration does not introduce the name?为什么隐式声明不引入名称?
【发布时间】:2018-02-28 06:21:54
【问题描述】:

我已经阅读了以下两个较早的问题,但仍然不能很好地理解。
1.Why do I need to #include when using the typeid operator?
2.When is #include library required in C++?

由于typeid 使用type_info 类,因此要求我们#include<typeinfo> 是合理的。 但是,new operators 也使用了std::bad_alloc,为什么它不需要我们#include <new>(我知道sizeof() 不需要<cstddef>,因为size_t 可以是在编译时替换为内置类型,只要编译器知道size_t实际上是什么。)

根据第二个问题中投票最多的答案,他说:

注意:隐式声明不引入名称 std、std::bad_alloc 和 std::size_t,或库用于声明这些名称的任何其他名称。因此,引用这些函数之一但不包括标头的 newexpression、delete-expression 或函数调用是格式正确的。但是,引用 std、std::bad_alloc 和 std::size_t 是格式错误的,除非已通过包含适当的标头来声明名称。

上面这段比较混乱,因为我们每次使用一个类型,都需要在使用前声明一个类型,比如class A;void foo(A*);,而void* operator new(std::size_t) throw(std::bad_alloc);隐式声明也有一个类型std::bad_alloc ,隐式声明是否有特权不声明它使用的类型?

【问题讨论】:

  • 有些类型是编译器内置的...
  • @BasileStarynkevitch 是不是因为c++标准告诉我们要这么做?
  • 不一定。 IIRC 编译器可能会预定义一些名称以 _ 开头的类型(它们是为实现保留的),并且一些标头可能 typedef 这些名称在标准中提及
  • 标准告诉我们如何编写程序。该标准还告诉编译器编写者他们的实现应该接受或拒绝哪些程序。如果您使用 std::bad_alloc 而不包含适当的标头,则实现应该拒绝您的程序因为标准告诉编译器编写者这样做
  • 另一个问题已经很老了,the declaration of operator new 没有提到bad_alloc 对标准的几次修订。

标签: c++


【解决方案1】:

前向声明用于名称查找。对于隐式声明,编译器已经知道这些名称的语义,所以不需要进行名称查找,因此不需要前向声明(即标头)。

关键是void foo(A*);写的,所以你必须通过前向声明告诉编译器A是什么,而隐式声明是编译器写的,因此您无需告诉编译器声明中使用的名称是什么。

请注意,上述原因不足以解释为什么在使用typeid 之前需要<typeinfo>。事实上,这个规则在标准[expr.typeid] paragraph 6中有明确的规定:

如果在使用 typeid 之前没有包含标头 <typeinfo>,则程序格式错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    相关资源
    最近更新 更多