• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

bona kim님과 같은 질문입니다~!

21.01.09 13:18 작성 조회수 173

1

Q)어떠한 이유로 main()의 첫 doSomething(); 유무에 따라 에러가 발생하는 건가요?

본 코드는 영상 (9:50)와 동일합니다. 단, main() 첫 줄에 doSomething()을 호출한 것만 다릅니다.

class Exception
{
public:
	void report()
	{
		cerr << "Exception report" << endl;
	}
};

class ArrayException : public Exception
{
public:
	void report()
	{
		cerr << "Array exception" << endl;
	}
};

class MyArray
{
private: int m_data[5];

public:
	int& operator [] (int index)
	{
		if (index < 0 || index >= 5)
			throw ArrayException();

		return m_data[index];
	}
};

void doSomething()
{
	MyArray my_array;

	try { my_array[100]; }
	catch (ArrayException& e)
	{
		cout << "doSomething() " << endl;

		throw e; // error break out!!
	}
}

int main()
{
	doSomething(); // only this line is different from before!!
	try
	{
		doSomething();
	}
	catch (ArrayException& e)
	{
		cout << "main()" << endl;

		e.report();
	}
	return 0;
}

위 코드는 사실상 doSomething에서 특정 대상을 throw할 필요없이 그냥 throw해도 main()의 catch가 받아줘야 하는 코드라고 생각해요.

test) throw e; vs throw; = 기능상 결과 똑같음(위 코드에 한에서만).

throw와 catch 순서 상 : class MyArray (throw) -> void doSomething (catch & throw) -> main (catch)

그런데 자꾸 런타임 에러가 발생합니다. 아래 사진, 또는 Unhandled exception 에러 발생.

(디버깅)본 에러는 doSomething의 throw이 작동하는 순간 발생합니다.

신기하게도 main()의 가장 첫 번째 doSomething();을 지워주면 이러한 문제가 발생하지 않고, 함수 doSomething안에 있는 throw도 main()의 catch까지 문제없이 전달됩니다.

답변 5

·

답변을 작성해보세요.

3

안소님의 프로필

안소

2021.01.10

안녕하세요!

첫 번째 doSomething(); 는 try-catch 문안에 있지 않기 때문에 첫번째 doSomething(); 의 예외를 받아 줄 catch 가 없기 때문입니다. 그래서 "예외 처리"가 되지 못하고 그냥 보통 런타임 에러 발생하듯이 에러 발생해서 끝나버린 것이에요.

try와 catch는 별개가 아니라 완전 하나의 문장이라고 보시면 됩니다. 짝꿍이에요. try 없인 catch도 없고 catch 없인 try도 없습니다. try와 catch 사이 중간에 다른 문장을 넣기만 해도 컴파일 에러가 발생할 정도로 완전 하나의 문장이에요! catch는 짝꿍인 try블록 안에서 발생한 예외만 받을 수 있습니다. 그래서 예외가 발생할 수도 있는 지역을 try로 묶는 것입니다.

첫번째 doSomething()의 함수 내부에서 throw e; 로 예외가 던져졌는데 이를 호출한 첫번째 doSomething()은 try문 안에 있는게 아니라서 던져진 e 예외를 받을 수 있는 catch가 없기 떄문이에요. 그래서 예외처리가 되지 못하고 그냥 예외 발생으로 에러가 발생한 것입니다. 밑에 있는 main 의 catch는 오로지 짝꿍인 try에 감싸진 두 번째 doSomething의 예외만 받을 수 있습니다. 첫 번째 doSomething의 예외는 받지 못합니다. 

1

안소님의 프로필

안소

2021.01.10

이해 되셨다니 다행입니다. 🥰

1

안소님의 프로필

안소

2021.01.10

아니요! 그 첫 번째 doSomething이 던지는 예외를 받고 싶으신거니까 첫 번째 doSomething 또한 try 블럭 내에 배치를 시켜야겠습니다.

네! 그렇게 doSomething()을 호출한 그 자리로 throw 되는데 그 throw를 받을 수 있는 예외처리를 애초에 하지 못하는 상황입니다. catch문은 try문 안에서 발생한 예외만 받을 수 있는데 질문자님께서 언급하신 그 첫번째 doSomething은 try문 안에 있지 않아 예외 처리를 할 수 없다는게 요지였습니다.

질문자님께서 이 첫 번째 doSomething 내에서 던져진 예외를 왜 main 함수의 catch들에서 받아 예외 처리 되지 않고 그냥 예외 발생이 되버리냐고 질문을 주신 것으로 이해를 해서, 첫 번째  doSomething은  try문 내에 있지 않아 던져진 예외를 받아 처리를 할 수 없다고 말씀을 드렸습니다. 말씀하신 main 함수의 catch문들은 두 번째 doSOmething()이 속해있는 try 블럭에서 발생한 예외들만 받을 수 있기 때문입니다.

0

홍길동님의 프로필

홍길동

질문자

2021.01.10

(번뜩)이해했어요! 감사합니다~!

0

홍길동님의 프로필

홍길동

질문자

2021.01.10

그럼 doSomething함수의 throw는 알아서 main()의 catch로 가는 것이 아니라 가장 첫 번째 줄로 throw되는 건가요?

다시 말해서 main()의 try 위에 머가 있으면 안되는건가요?

답변 감사합니다.