尽管未定义<new>标头,但新抛出bad_alloc?

时间:2016-01-19 15:54:07

标签: c++ c++11 bad-alloc

如果没有new(因为此错误is defined in the <new> header),程序中的bad_alloc表达式怎么会抛出#include <new>错误?

从3.7.4开始。 N3337:

  

该库提供全局分配和释放功能的默认定义。一些全局分配和释放功能是可替换的(18.6.1)。 C ++程序最多只能提供一个可替换分配或释放功能的定义。任何此类函数定义都将替换库中提供的默认版本(17.6.4.6)。以下分配和释放函数(18.6)在程序的每个翻译单元中在全局范围内隐式声明。

void* operator new(std::size_t);

void* operator new[](std::size_t);

void operator delete(void*);

void operator delete[](void*);
     

这些隐式声明仅引入函数名称operator newoperator new[]operator deleteoperator delete[]。 [注意:隐式声明不会引入名称stdstd::size_t或库用于声明这些名称的任何其他名称。因此,一个新表达,   delete-expression或函数调用引用这些函数之一而不包括标题<new>是格式正确的。但是,除非通过包含适当的标头声明了名称,否则引用stdstd::size_t的格式不正确。 -end note ]也可以为任何类声明和定义分配和/或释放函数

这对我来说仍然不清楚。隐式声明使用std::size_t但不引入它们(bad_alloc的情况必须相同)?在使用std::size_t表达式之前,不需要引入new吗?可以理解这是怎么回事,或者我必须以面值来看待它?

3 个答案:

答案 0 :(得分:4)

名称std::size_t只是其他整数类型的typedef,可能是unsigned longunsigned long long。编译器知道new的实际参数类型,即使名称size_t不可见。

类似于bad_alloc。抛出bad_alloc的运行时代码肯定包含<new>标题,即使您的程序没有。

答案 1 :(得分:4)

你的引述说这些全局函数存在并且如所描述的那样隐式声明。因此,当您调用new时,将调用标准库中的全局函数。全局函数new的实现是抛出std::bad_alloc的实现,并且该实现在编译时可以访问<new>,因此知道如何抛出std::bad_alloc。您的代码不需要知道std::bad_alloc是什么,除非您试图抓住它。但除了捕获它之外,这就像你从其他库调用任何其他函数可能会抛出一些任意异常。除非你试图抓住它,否则你不需要知道该异常的细节,但这并不能阻止被调用者抛出异常。

答案 2 :(得分:3)

允许C ++标准头包含任何其他C ++头。因此,您可以在不包含<form id="yourForm"> <input type="text" name="inlineViewProvider_ONLYOFFICE_URL" /> .... </form> 的情况下获得std::bad_alloc的依赖于实现的访问权限,并且可以<new>包含std::size_t等。我懒得在你的标准版本中查找它,但在N4296草案中它是在§17.6.5.2中:

  

C ++标头可能包含其他C ++标头。

您可以使用编译器尝试此操作。

<cstddef>

现在让我们添加一个完全不相关的int main() { std::size_t x; // error std::bad_alloc y; // error }

#include