I'm trying to figure out the proper way of using the noexcept attribute. I've already spent half a day trying to understand it, but I'm not sure I did. And I don't want to use or not to use noexcept everywhere mindlessly.
Question: Do I understand it right, that if a function calls only functions that have noexcept attribute, then we may (or should) safely mark our function as noexcept too?
Suppose, I have functions that check whether a provided path exists and is a directory. I use filesystem for that purpose. One function (IsDir) calls exists and is_directory functions that are not marked as noexcept. The other function (IsDir2) calls exists and is_directory functions that are marked as noexcept. Can I safely mark the second function as noexcept?
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
bool IsDir(const fs::path& p) {
const bool exists{ fs::exists(p) }; // Not marked as "noexcept".
const bool is_dir{ fs::is_directory(p) }; // Not marked as "noexcept".
return exists && is_dir;
}
bool IsDir2(const fs::path& p, std::error_code& ec) noexcept {
const bool exists{ fs::exists(p, ec) }; // "noexcept" version.
const bool is_dir{ fs::is_directory(p, ec) }; // "noexcept" version.
return exists && is_dir;
}
int main () {
const fs::path p("~/Some_Path");
std::cout << std::boolalpha << IsDir(p) << std::endl;
std::error_code ec;
std::cout << IsDir2(p, ec) << std::endl;
return 0;
}
There are 2 scenarios when you'd want to mark a function:
std::terminate, if a function would otherwise "escape" the function.If only the former is the desired effect, there are several things that you need to take into consideration:
noexceptin all scenarios. Some libraries are pre-C++11 compatible and the keyword wasn't even available. Some libraries didn't want to risk ABI breaks or didn't consider it worth the effort adding the keyword in. Some libraries need to be compatible with C, where the keyword isn't available; this includes functions in the C++ standard library such asstd::strlen. In some cases where templates are involved, the required conditionalnoexceptspecification could get too complicated for the implementor to bother.In your
IsDir2your analysis regarding no exception being thrown inside the function body, so marking it asnoexceptis appropriate, but as noted by @paxdiablo in the comments the implementation of the function may require an overhaul.