While working on an exercise for my C++ class where we were working on Exception handling, I came across a puzzling issue. I initially had the following exception handler (Please don’t roast the use of int
s as exceptions, this was the task we were given):
#include <iostream>
//...
try {
// Code that throws an int
}
catch(const int errno) {
std::cout << errno << std::endl;
}
To the untrained eye, this would seem like a normal declaration of an integer exception variable. However, the unsafe code kept evading the catch block, despite throwing an integer itself. After some investigation, it turned out that a Macro in errno.h
declared #define errno (*__errno_location ())
caused a Macro Expansion into the following code
try {
// Code that throws an int
}
catch(const int (*__errno_location())) {
std::cout << (*__errno_location()) << std::endl;
}
I was unsure what exactly is being declared in the catch Expression. I tried using C Gibberish to English, but unsurprisingly that didn’t help much, telling me that it was declaring a function returning an int*
. ChatGPT was also puzzled by this expression, calling it “unconventional formatting”.
Playing around with it a little, I came up with the following code:
const int *blah() {
return new int(10);
}
int main() {
try {
throw &blah;
}
catch(const int *foo()) {
std::cout << *foo () << std::endl;
}
}
Which outputs the number 10 to the console. Changing the values in the integer constructor also causes that integer to be output to the console as well. So my current hypothesis is that const int *foo()
is declaring that a function pointer returning an int pointer be caught in this catch block, and in the print statement we simply call that function and dereference the pointer. I would like my hypothesis be verified or corrected by more experienced C++ programmers though.