12 Feb
2015
Posted in: 코드
By    10 Comments

[플밍노트] 방어적 프로그래밍


[플밍노트] 방어적 프로그래밍
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaru, http://www.jiniya.net

HRESULT SomeFunc(...)
{
	// ...

	SIZE_T written;

	std::vector<xch> buffer;
	buffer.resize(MAX_BODY_CONTENT);

	HRESULT hr = dn->ToBuffer((PVOID) &buffer[0], buffer.size(), &written);
	if(!SUCCEEDED(hr))
		return hr;

	buffer[written] = '\0';

	// ...
}

위와 같은 코드를 줬더니 그대로 사용해서 “buffer[written] = ‘\0′;” 구문에서 written이 MAX_BODY_CONTENT보다 크면 어쩌냐는 이야기를 했다. 그랬더니 dn->ToBuffer 함수가 실패한 경우에도 written에 값이 저장되냐는 둥, 소스가 더 커도 실제 크기가 written에 넘어오냐는 등의 질문을 한다.

dn->ToBuffer 함수가 어찌 동작하든 간에 if문 하나만 추가하면 안전해지는 문제 아니냐는 말을 했더니 기어코 소스 코드를 찾아내서는 그렇게 반환하는 경우는 없는것 같다고 궁시렁거리는 신입 프로그래머의 패기. dn->ToBuffer 함수가 내일 동작이 바뀌어서 그런 값을 반환하면 어쩔거냐고 했더니 그제서야 if문을 추가한다.

다른 함수에 불필요한 가정을 추가하지 말자. 불필요한 가정이 필요하다면 그 가정이 사실인지 반드시 확인하자 (ASSERT가 됐든 if가 됐든). 그리고 다른 함수가 정상 동작할 거라는 일말의 기대도 하지 말자.

돈을 받고 갈켜줘도 시원찮을 판에 월급 주며 갈켜주는데도 엉뚱 소리를 하니 속에 천불이 ㅠㅜ~
참 갑갑한 현실…

안개가 짙은 길을 주행할 땐 일단 서행하렴. 눈 앞에 갑자기 차가 나타날 수 있단다.

운전이나 코딩이나 방어가 중요하다는 거…


  • 트랙백 주소: http://www.jiniya.net/wp/archives/14694/trackback

관련 글

  • http://netpyoung.github.io/ EunPyoung Kim

    아, 신입분의 생각이 맞는것 같기도 하고, 또 글을 읽어보니 또 영진님의 말도 맞는것 같고.. 저 스스로 확신이 없는걸보니 부족한 것을 느낍니다.

    그나져나 신입분은 복받았네요, 이렇게 생각해주면서 말해주는 사수분도 있고 ㅎㅎ.

    ps. 이 블로그를 구독하면서, 올라오는 글들을 읽으며 많은 생각을 했었네요. 매번 좋은 글(생각)공유 감사드립니다 (_ _).

  • Seongki Shin

    내용도 그렇고, 사진도 그렇고 전적으로 동감입니다.

  • Lyn

    서버 함 터져봐야 정신 차리겠네 ㅋㅋㅋ

  • 커피앤피아노

    written이 MAX_BODY_CONTENT보다 크면 어쩌냐는 이야기를 했다. >= written이 MAX_BODY_CONTENT보다 같거나 크면 어쩌냐는 이야기를 했다.로 변경해야 될꺼 같아요..

  • 쟁이

    무결성도 중요하지만 쓸데없는 오버헤드는 불필요하겠죠. ToBuffer()에는 버퍼의 크기가 전달되었으므로 버퍼크기를 초과했다면 함수가 실패했을테고 그러면 바로 리턴해 버릴 수도 있겠죠.(물론 확인도 필요하지만…)

    robust한 코드를 만들기 위해서 함수 본체에 방어 코드를, 호출 코드에서도 방어 코드를 넣는다면 그 코드가 얼마나 자주 호출되느냐에 따라 엄청난 뻘짓으로 리소스를 낭비하는 결과를 초래할 수도 있을것입니다.
    신입에게 무엇을 가르쳐주고 싶은지는 백분 이해하지만….

  • YoungJin Shin

    버퍼크기를 초과했다면 함수가 실패했을테고 그러면 바로 리턴해 버릴 수도 있겠죠. <== 이게 불필요한 가정입니다. 함수가 버퍼 크기만큼 복사하고 성공을 리턴할 수도 있다고 가정할 수도 있지요.

    가정에 의존해야 하는 코드를 작성하지 않는 것이 좋다는 것이죠. 정 성능이 문제가 된다고 판단됐다면 ASSERT라도 사용하는 것이 가정의 진위를 더 빨리 판별할 수 있게 해주었을겁니다.

  • YoungJin Shin

    맞습니다. 그래서 수정을 한 번 더 했지요. ㅠㅜ

  • YoungJin Shin

    서버는 정말 ㅠㅜ~ 눈물 좀 닦고… ㅋㅋㅋ

  • YoungJin Shin

    감사합니다.

  • YoungJin Shin

    좋은 댓글 감사합니다 ^^