在为我的 C++ 课程进行异常处理练习时,我遇到了一个令人费解的问题。我最初有以下异常处理程序(请不要将
int
用作异常,这是我们被赋予的任务):
#include <iostream>
//...
try {
// Code that throws an int
}
catch(const int errno) {
std::cout << errno << std::endl;
}
对于未经训练的人来说,这看起来像是整数异常变量的正常声明。然而,尽管不安全代码本身抛出了一个整数,但它仍然不断地逃避 catch 块。经过一番调查,发现
errno.h
中声明 #define errno (*__errno_location ())
的宏导致宏扩展为以下代码
try {
// Code that throws an int
}
catch(const int (*__errno_location())) {
std::cout << (*__errno_location()) << std::endl;
}
我不确定 catch 表达式中到底声明了什么。我尝试使用 C Gibberish to English,但毫不奇怪,这并没有多大帮助,告诉我它正在声明一个返回
int*
的函数。 ChatGPT 也对这种表达感到困惑,称其为“非常规格式”。
稍微尝试了一下,我想出了以下代码:
const int *blah() {
return new int(10);
}
int main() {
try {
throw &blah;
}
catch(const int *foo()) {
std::cout << *foo () << std::endl;
}
}
将数字 10 输出到控制台。更改整数构造函数中的值也会导致该整数也输出到控制台。所以我当前的假设是
const int *foo()
声明一个返回 int 指针的函数指针被捕获在这个 catch 块中,并且在 print 语句中我们简单地调用该函数并取消引用该指针。我希望我的假设能够被更有经验的 C++ 程序员验证或纠正。
errno
是实现定义的。请参阅cppreference:
errno 是一个用于错误指示的预处理器宏。它扩展为静态(C++11 之前)线程局部(C++11 起)类型为
的可修改左值。int
根据您已经发现的内容,我们可以得出结论,
__errno_location()
是一个函数(或某些可调用函数),返回指向int
的指针,该指针对您正在使用的实现上的最后一个错误进行编码。
正如评论中提到的,标识符
errno
被 POSIX 保留。