Another option is to re-design the API so that the error doesn't occur.
void windowDestroy(Window &window)
{
glfwDestroyWindow(window.handle);
}
bool windowShouldClose(const Window &window)
{
const bool res = glfwWindowShouldClose(window.handle);
#ifdef DEBUG
CHECK_GLFW_ERROR();
#endif
return res;
}
A downside is that the interface may be less familiar, but if you have the freedom to design the API it's an option.
The defensive approach feels "safer" and provides a clearer, more professional error message.
This ^^^. Forget about "professional". It is "clearer" that matters.
It's essentially enforcing a precondition that I, as the user, have already agreed to follow.
Ahh, if we could only trust ourselves. Then there would be no bugs, and actually no language would be necessary, maybe except C (as a portable assembly).
In the case that the precondition is not satisfied, well too bad... you crash!
So you don't care about the code crashing? You should, you are the one writing it. :) And let me repeat again: it is a lot easier to debug and fix an exception instead of crash.