switch 문의 최적화

내가 하는 일 중에는 API를 만드는 일도 한다. 그러다 보면 return type이 스펙에 맞게 제대로 되었나를 알아 보기 위해 negative test에 대한 test case를 만든다.

그 중에 enum의 경우는 사용자가 악의를 가지고 범위에서 벗어난 파라미터를 줄 수가 있으므로 그것에 관해서도 체크를 해야 한다. 예를 들어, A와 B만들 가지는 enum에 대해 강제로 음수나 아주 큰 양수를 보내는 행위 등을 막기 위함이다.

그래서 enum에 대해 허용된 값만을 넘겼는지는 체크하기 위한 다음의 매크로를 만들었다.

// 2개의 field를 가지는 enum 타입에 대한 값 체크
#define CHECK_INVALID_ENUM_X2(source, case1, case2) \
switch (source) \
{ \
case case1: \
case case2: \
break; \
default: \
return false; \
}

// 3개의 field를 가지는 enum 타입에 대한 값 체크
#define CHECK_INVALID_ENUM_X3(source, case1, case2, case3) \
switch (source) \
{ \
case case1: \
case case2: \
case case3: \
break; \
default: \
return false; \
}

2개 또는 3개의 값만 가지는 emul에 대해 주어진 파라미터의 값이 허용된 값 안에 있는지를 알아 보고, 그렇지 않을 때는 false를 리턴하게 되어 있다. (실제로는 last error나 error log 등을 세팅하기 때문에 더 복잡하지만...)

사실 이 macro는 특별한 문제가 없다. 다만 앞으로 이야기할 아주 특수한 경우를 빼고 말이다.

문제의 상황을 만들어 보기 위해 간단한 enum 2개와 API를 만들어 보았다.

enum EA { EA_1, EA_2 };
enum EB { EB_1, EB_2, EB_3 };

bool SetSomething(EA a, EB b)
{
CHECK_INVALID_ENUM_X2(a, EA_1, EA_2);
CHECK_INVALID_ENUM_X3(b, EB_1, EB_2, EB_3);

// SetSomethingInternal(a, b);

return true;
}

유효한 값이 2개가 있는 EA라는 enum과 유효한 값이 3개가 있는 EB라는 enum이 있고, SetSomething()이라는 API는 제일 먼저 a와 b라는 이름으로 들어 온 파라미터의 유효성을 체크한다.

그리고 나는 이 매커니즘이 제대로 작동하는 가를 확인 하기 위해 다음과 같은 test case를 만들었다.

#include <stdio.h>

int main()
{
bool r1 = SetSomething(EA(-1), EB_1);
bool r2 = SetSomething(EA_1, EB(-1));

printf("r1 = %d, r2 = %d\n", r1, r2);
return 0;
}

아마도 쉽게 구할 수 있는 유명한 컴파일러에서는 대부분 r1 = 0, r2 = 0 이라는 결과를 돌려 받게 될 것이다. 하지만 조금 이름이 알려진 어떤 회사의 embedded compiler에서는 이 결과가 r1 = 1, r2 = 0 과 같이 나왔다. 다양한 컴파일러에서 작업해야 하는 일이 하나의 업이 된 지금, 이렇게 동작이 다른 컴파일러를 보는 것은 그리 이상한 일은 아니다. 다만 문제를 분석해서 아무런 문제가 없는 코드로 만드는 것이 조금 귀찮은 일일 뿐이다.


Test case가 특정 기기에서는 일부 fail이 나온다는 보고를 받고는  바로 디버깅 작업을 시작하였다. 그리고는 놀라운(?) 사실을 알아 내었다. 일부 컴파일러에서는 최적화 옵션에 따라서는 CHECK_INVALID_ENUM_X2() 매크로 자체가 아예 코드에서 빠진다는 것이다.

유효 값이 2개 밖에 없는 enum에 대해 그것을 switch 문으로 분기를 하면, 내부적으로 if - else 문으로 바꾸게 되고, 이때는 if 쪽이나 else 쪽이나 코드가 break 밖에 없기 때문에 코드를 삭제하는 만행(?)을 저지른 것이다. 다만, emul이 3개가 있는 경우는 if - else 로 바뀌지 않기 때문에 위와 같은 최적화의 대상이 아니라 제대로 동작하는 것이다.

이런 경우는 직접 부딪쳐 경우를 파악할 수 밖에는 없는 것이다. 그리고 최대한 에러 체크를 하기 위한 부분은 최적화에 안 걸리는 쪽의 코드를 짤 수 밖에 없다. 위의 경우도 MACRO를 if (!(A and B)) 문으로 치환하여 해결하였다.

Posted by 안영기

2011/06/04 19:50 2011/06/04 19:50
Response
0 Trackbacks , 1 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/30

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

« Previous : 1 : ... 16 : 17 : 18 : 19 : 20 : 21 : 22 : 23 : 24 : ... 50 : Next »

블로그 이미지

게임 개발을 기반으로 한, 잡다한 개발 기록 저장소

- 안영기

Notices

Archives

Authors

  1. 안영기

Recent Comments

Recent Trackbacks

Calendar

«   2024/03   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

Site Stats

Total hits:
235562
Today:
23
Yesterday:
38