set_new_handler and errno
set_new_handler and errno
如果您使用 set_new_handler
并且调用了您的处理程序函数,是否保证errno
被设置,就像从 malloc
返回 0 一样?还是使用strerror(ENOMEM)
更好? errno
适用于Microsoft C++和 GCC,但这仍然留下了它是否得到保证的问题。
我认为errno
不足以检测动态内存分配故障。查看 N3337,特别是 3.7.4.1 分配函数:
2 [...]即使请求的空间大小为零,请求也可能失败。 如果请求成功,则返回的值应为非空指针值 (4.10) p0,不同于任何 以前返回的值 P1,除非该值 P1 随后传递给运算符 delete。这 取消引用作为零大小请求返回的指针的影响是不确定的。35
3 分配存储失败的分配函数可以调用 当前安装的新处理程序函数 (18.6.2.3)(如果有)。[ 注:A 程序提供的分配函数可以获取 当前安装new_handler使用 std::get_new_handler 函数 (18.6.2.4)。—尾注 ] 如果声明了分配函数 使用非抛出异常规范 (15.4) 无法分配 存储,它应返回一个空指针。任何其他分配函数 未能分配存储的应仅通过抛出来指示故障 与类型的处理程序 (15.3) 匹配的类型异常 标准::bad_alloc (18.6.2.1).
脚注35(这只是指示性的,非规范性的):
35) 目的是通过调用 std::malloc() 或 std::calloc() 来实现运算符 new(),因此规则实质上是 一样。C++与 C 的不同之处在于要求零请求返回非空指针。
现在,转到 C 标准草案,N1570 并查看 7.5 错误<errno.h>
:
3 初始线程中 errno 的值在程序启动时为零(初始值为 其他线程中的 errno 是一个不确定的值),但永远不会被任何库设置为零 function.202) errno 的值可以通过库函数调用设置为非零值 是否存在错误,前提是 errno 的使用未记录在 本标准中对功能的描述。
似乎errno
可能由malloc
故障设置,但这不是必需的。
此外,N1570的7.22.3内存管理功能没有指定malloc
或朋友需要设置errno
。
我的建议是坚持标准保证的内容并使用new
抛出的异常(std::bad_alloc
)(即不使用无抛出new
)。
new
(或malloc
,就此而言)设置errno
。 两者都有明确定义的错误报告语义(抛出std::bad_alloc
或返回空指针),这不涉及errno
。 (从实现质量的角度来看,我不希望允许new
或malloc
修改errno
。 不遵守 Posix 要求。
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- 重新定义预定义的 errno 错误消息 (E2BIG)
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- C++ getenv and setenv
- Inference pytorch C++ with alexnet and cv::imread image
- Visual Studio 2019 C++ and std::filesystem
- 保证逻辑 AND 表达式中的函数调用
- set_new_handler and errno
- epoll and negative errno value
- SSL_shutdown() returns -1 and errno is 0