๐ก ๋ณธ ๋ฌธ์๋ '๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ: ์์ธ ์ฒ๋ฆฌ'์ ๋ํด ์ ๋ฆฌํด๋์ ๊ธ์ ๋๋ค.
ํ๋ก๊ทธ๋๋ฐ์ ํ๋ค๋ณด๋ฉด ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ๊ฒ๋ ์ค์ํ์ง๋ง, ์ถฉ๋ถํ ์์ธก์ด ๊ฐ๋ฅํ ์์ธ์ ๊ฒฝ์ฐ๋ผ ํ ์ง๋ผ๋ ์์ธ ์ฒ๋ฆฌ๊ฐ ํ์ํ ๋๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌํ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ Exception ์ฒ๋ฆฌ์ ๋ํด ๋ค๋ฃจ๋ฉฐ ์ฃผ์ํด์ผํ ์ฌํญ์ ๋ํด์๋ ์ ๋ฆฌํด๋์์ผ๋ ์ฐธ๊ณ ๋ถํ๋๋ฆฝ๋๋ค.
1. Try-Catch-Throw
- try ๋ฌธ : ์์ธ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ฝ๋ ๋ธ๋ก
- throw ๋ฌธ : try ๋ฌธ์์ ๋ฐ์ํ ์ค๋ฅ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๋ฌ
- catch ์ : ๋ฐ์ํ ์์ธ์ ๋ํด ์์ธ ํธ๋ค๋ฌ๊ฐ ์ฒ๋ฆฌํ ๋ด์ฉ์ ๋ด์ ์ฝ๋ ๋ธ๋ก
try { // ์์ธ๊ฐ ๋ฐ์ํ๋ ์์ญ
if (์์ธ ์กฐ๊ฑด) throw ์์ธ ๊ฐ์ฒด; // ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ์์ธ๋ฅผ ๋์ง๋ ์์ญ
}
catch (์์ธ ๊ฐ์ฒด) { // ๋์ ธ์ง ์์ธ๋ฅผ ์ก๋ ์์ญ
// ์์ธ ์ฒ๋ฆฌ ์์ญ
}
vector์ ๊ฐ์ด sequencial container์ ๊ฒฝ์ฐ, []operator๋ฅผ ์ฌ์ฉํ์ง ์๊ณ .at ๋งค์๋๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ exception ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
try {
std::vector<int> v(3); // ํฌ๊ธฐ๊ฐ 3 ์ธ ๋ฒกํฐ ๋ง๋ฆ
std::cout << v.at(4);
} catch (std::out_of_range const &e) {
std::cout << e.what() << '\n';
} catch (std::exception const &e) {
std::cout << e.what() << '\n';
}
2. Throw (์์ธ ๋์ง๊ธฐ)
2.1 ๋ค์ค catch ๊ตฌ๋ฌธ
auto exprint = [](std::exception const & e)
{
fmt::print("{}\n", e.what());
};
try {
throw std::runtime_error("timed out");
} catch (std::system_error const & e) {
exprint(e);
} catch (std::runtime_error const & e) {
exprint(e);
} catch (...) { // ๋ง์ง๋ง catch(...) ์์ try ์์์ ๋ฐ์ํ ๋ชจ๋ ์์ธ๋ค์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
fmt::print("unkown exception\n"");
}
- catch๋ฌธ์ ์์์๋ถํฐ ์๋๋ก ๋ด๋ ค๊ฐ๋ฉด์ '์์ธ' ๋ฐ์ดํฐ์ ํ๋นํ catch๋ฌธ์ ์ฐพ์ต๋๋ค.
- ๊ทธ๋ฌ๋ ์์ ๊ตฌ์กฐ์ ํด๋์ค ์๋ฃํ์ ๋ ์ด์ catch๋ฌธ์ ๊ธฐ์ ํ๊ฒ ๋๋ฉด ์ ๋๋ ์์๋๋ก catch๋ฌธ์ ๊ธฐ์ ํฉ์๋ค.
2.2 Throw: std::string
string์ throw ํ๊ณ ์ถ์ ๊ฒฝ์ฐ, ๋ค์์ ๋งค๋ด์ผ์ ๋ฐ๋ผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
//Good, because manual memory management isn't needed and this uses less heap memory (or no heap memory) so this is safer if used in a low memory situation
try { throw string("foo"); }
catch (string s) { cout << s << endl; }
//Valid, but avoid manual memory management if there's no reason to use it
try { throw new string("foo"); }
catch (string* s) { cout << *s << endl; delete s; }
//Best. Just a pointer to a string literal, so no allocation is needed, saving on cleanup, and removing a chance for an allocation to fail.
try { throw "foo"; }
catch (const char* s) { cout << s << endl; }
2.3 noexcept ๊ตฌ๋ฌธ
ํ์คํ๊ฒ ์๋ฌ๋ฅผ ๋ด๋ณด๋ด์ง ์๋ ํจ์๊ฐ ์๋ค๋ฉด noexcept ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
- noexcept ํค์๋๋ฅผ ๋ถ์ด๋ ์ด์ ๋ ๋จ์ํ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ปดํ์ผ๋ฌ์๊ฒ ์ฃผ๋ ํํธ๋ผ๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค.
์ปดํ์ผ๋ฌ๊ฐ ์ด๋ค ํจ์๊ฐ ์ ๋๋ก ์์ธ๋ฅผ ๋ฐ์์ํค์ง ์๋๋ค๋ ์ฌ์ค์ ์๋ค๋ฉด, ์ฌ๋ฌ๊ฐ์ง ์ถ๊ฐ์ ์ธ ์ต์ ํ๋ฅผ ์ํํ ์ ์์ต๋๋ค. - ์ฐธ๊ณ ๋ก, ํจ์์ noexcept ํค์๋๋ฅผ ๋ถ์๋ค๊ณ ํด์, ํจ์๊ฐ ์์ธ๋ฅผ ์ ๋๋ก ๋์ง์ง ์๋๋ค๋ ๊ฒ์ ์๋๋๋ค.
noexcept ๋ก ๋ช ์๋ ํจ์๊ฐ ์์ธ๋ฅผ ๋ฐ์์ํค๊ฒ ๋๋ค๋ฉด ์์ธ๊ฐ ์ ๋๋ก ์ฒ๋ฆฌ๋์ง ์๊ณ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋ฉ๋๋ค.
void func() noexcept { ... }
+ memory ๊ด๋ จ ๋ฌธ์
์ถ๊ฐ์ ์ผ๋ก memory ๊ด๋ จ ๋ฌธ์ ์ ๊ฒฝ์ฐ๋ Try-Catch๋ก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ์ง ๋ชป ํฉ๋๋ค.
3. Exception ์์
exception์ ์ฌ์ฉ์์ ๋ง์ถฐ ์ ์ํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ด ์์์ ๋ฐ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
#include <exception>
#include <iostream>
class Parent : public std::exception {
public:
// what ์ std::exception ์ ์ ์๋ ํจ์๋ก, ์ด ์์ธ๊ฐ ๋ฌด์์ธ์ง ์ค๋ช
ํ๋ ๋ฌธ์์ด์ ๋ฆฌํดํ๋ ํจ์ ์
๋๋ค.
virtual const char* what() const noexcept override { return "Parent!\n"; }
};
class Child : public Parent {
public: const char* what() const noexcept override { return "Child!\n"; }
};
4. Exception ์ฌ์ฉ์ ์ฃผ์ํ ๊ฒ
4.1 Exception ์ฃผ์ ์ฌํญ
- ์์ธ์ฒ๋ฆฌ try-catch๋ ๊น๋ํ๊ธด ํ์ง๋ง ์ฌ์ฉํ๋ฉด ํ ์๋ก ํ๋ก๊ทธ๋จ ์ฑ๋ฅ์๋ ์ ์ํฅ์ ๋ฏธ์ณ์ ๋ฌด์์ ์ฌ์ฉํ๋ฉด ์๋ฉ๋๋ค.
- ์ถฉ๋ถํ ์์ธก์ด ๊ฐ๋ฅํ ์์ธ์ ๊ฒฝ์ฐ, ์์ธ๋ฅผ ํด์ฃผ๊ธฐ๋ณด๋ค๋ ์ ๋ ๊ฒ ์ฌ์ฉํ์ง ์๋๊ฒ์ ์ค์ ์ผ๋ก ๋ฌ์ผ๋ฉ๋๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ์๋ฒ๊ฐ์ ๊ฒฝ์ฐ์์ ์ ๋ ฅ๊ฐ์ ์ค์ผ์ด ๋ฐ์ํ๋๋ฑ์ ์์ธกํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์๊ฒจ ํฐ ๋ฌธ์ ๊ฐ ์ผ์ด๋๋ฉด ์๋๊ธฐ์ ํน์ ์์ธ๊ฐ ๋ฐ์ํ์ฌ๋ ์๋ฒ๊ฐ ๊ฐ์ ๋ก ์ข ๋ฃ๋์ง ์๊ณ ๋ฒํฐ๋๋ก ํ๋ ๊ฒฝ์ฐ์ ์ข ์ข ์ฌ์ฉ๋ฉ๋๋ค.
4.2 ๊ทผ๋ฐ Exception ์..? ์ฑ๋ฅ ์ ์ํฅ...
์ผํ ๋ณด๋ฉด… ๊ฐ๋
์ฑ๋ ์๊ณ ๋ชฐ์์ ์ฒ๋ฆฌํ๋ ๊ฒ๋ ๊ด์ฐฎ๊ณ ‘์ค ์ด๊ฑฐ ์จ์ผ ๊ฒ ๋ค!’ ์๊ฐํ๊ธฐ ์ฝ์ต๋๋ค.
ํ์ง๋ง... ์ฌ์ฉํ๋ฉด ํ ์๋ก ํ๋ก๊ทธ๋จ ์ฑ๋ฅ์๋ ์
์ํฅ์ ๋ฏธ์ณ์ ๋ฌด์์ ์ฌ์ฉํ๋ฉด ์๋ฉ๋๋ค.
- ํ๋ก๊ทธ๋จ ์ฉ๋๋ ์ปค์ง๊ณ , ํ๋ก๊ทธ๋จ ์ฑ๋ฅ์ด ๋์ ๋๊ฒ ๋๋ ค์ง๋๋ค(์คํ ๋๊ฐ๊ธฐ ๋ฑ ๋๋ฌธ์)
- ๋์ ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํด์ ์๋ ์ ์์ผ๋ฉฐ,
- ๊ฒฐ์ ์ ์ธ ์๋ฌ๋ฅผ ๋ชป ์ฐพ๋ ๊ฒฝ์ฐ ์์ต๋๋ค.
๋ฐ๋ผ์... ์ถฉ๋ถํ ์์ธก์ด ๊ฐ๋ฅํ ์์ธ์ ๊ฒฝ์ฐ, ์์ธ๋ฅผ ํด์ฃผ๊ธฐ๋ณด๋ค๋ ์ ๋ ๊ฒ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ ์ค์ ์ผ๋ก ๋ฌ์ผ๋ฉ๋๋ค.
+ ์ฌ๊ธฐ์ ์คํ ๋๊ฐ๊ธฐ๋? ํจ์ ์คํ ์ค throw๋ฅผ ๋ง๋๋ฉด ๋์๋๋ catch๋ฅผ ์ฐพ๊ธฐ ์ํด ํธ์ถ์์ผ๋ก.
- ํจ์๊ฐ ํธ์ถ๋ ๋๋ ์คํ์ ๊ฐ ํจ์์ ์คํํ๋ ์์ด ์์ฑ๋ฉ๋๋ค.
- ํธ์ถ ์ง์ ํธ์ถ ํจ์(์๋ธ๋ฃจํด)๊ฐ ๋๋๊ณ ๋์์ฌ ์ฃผ์๋ฅผ ํธ์ถ ์คํ(call stack)์ ๋ฃ์ต๋๋ค.
- ํธ์ถ ์คํ์ ๋ค์ด๊ฐ๋ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์๋ธ๋ฃจํด ์ข ๋ฃ ์งํ ๋์๊ฐ ์ฃผ์
- ์ง์ญ ๋ณ์
- ๋งค๊ฐ ๋ณ์
- ํจ์๊ฐ ๋ฆฌํดํ ๋ ์คํํ๋ ์์ ์ ํํ๊ฒ ํธ์ถ ์ง์ ์ผ๋ก ๋์๊ฐ๋ฉฐ, ํธ์ถ ์คํ์ ์๋ ์ ๋ณด๋ throw ๋ฐ์์ ์ ๋ถ ์ ๋ฆฌ๋ฉ๋๋ค.
- ์ด ์์ํจ์ catch๋ก ์ ์ด๋๋ ๊ณผ์ ์์ ์ค๊ฐ์ ์๋ ์ค๋ฅ๋ค์ด ์ฌ๋ผ์ง๊ณ ํด๋น ์คํ ์ ์ค๋ฅ ์ ๋ณด๋ง ์ ๋ฌ๋ฉ๋๋ค.
- ์ค๊ฐ์ ์๋ ์ค๋ฅ๋ค๊น์ง ์ ๋ฌํ๊ณ ์ถ์ผ๋ฉด?
- SHE(Structured Exception Handle) ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
- SHE์ ๋ํ ์์ธํ ์ค๋ช
์ ๋ค์์ ๋งํฌ๋ฅผ ์ฐธ์กฐํ์๊ธฐ ๋ฐ๋๋๋ค.
https://docs.microsoft.com/ko-kr/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-170
4.3 try-exception benchmark ์ธก์
์ฐธ๊ณ
- [์น์ด๋จน๋ C++] ์์ธ ์ฒ๋ฆฌ: https://modoocode.com/230
- [Coding Factory] ์์ธ ์ฒ๋ฆฌ (Exception Handling) try, catch ,throw: https://coding-factory.tistory.com/706
- [TCP School] try, throw, catch: http://www.tcpschool.com/cpp/cpp_exception_intro
- [C++] Try CATCH ์ด๋๊น์ง ๊ฐ๋ดค๋: https://dokumen.tips/engineering/c-try-catch-.html?page=9
- [stackoverflow] c++ string exception: https://stackoverflow.com/questions/134569/c-exception-throwing-stdstring