본문 바로가기

Programming/C Programming

전처리기 사용 : define ##


오랫만에 C에 대한 내용으로 포스팅을 하는군요.
개발을 하다 포트 번호에 따라 다른 레지스터를 사용해야 하는 일이 있었는데요.
레지스터를 보니 포트 번호에 따라 숫자만 다르고 같은 문자열을 가지더군요.

S3C2410_TCON_T1MANUALUPD
S3C2410_TCON_T2MANUALUPD
S3C2410_TCON_T3MANUALUPD

이런식의 레지스터가 여러게가 있어서 레지스터가 하나 변경될때마다 여기저기 찾아다니며 수작업을 해주어야 합니다.
포트를 진행하는 모델에 따라 변경해야 하는데 이걸 하드코딩으로 하자니 왠지 폼이 안나구요..
실수라도 하는 날엔 디버깅으로 날려먹을 시간을 생각하니 먼가 "다이나믹"하게 적용하고 싶더군요.
그래서 아래와 같이 작업을 해 보았습니다.

#define PWM_PORT_NUM 1

#define S3C2410_TCON_MANUALUPD(port_num) \
S3C2410_TCON_T##port_num##MANUALUPD

void foo()
{
 tcon |= S3C2410_TCON_MANUALUPD(PWM_PORT_NUM);
}

이제 PWM_PORT_NUM 선언만 변경해주면 자동적으로 레지스터가 변경되게 되지요.
우쭐한 마음으로 컴파일을 돌려보았는데 결과는 처참하였습니다.

error: 'S3C2410_TCON_TPWM_PORT_NUMMANUALUPD' undeclared

컴파일러 마다 전처리계 처리의 우선순위가 있겠지만 우리의 gcc 는 함수 형태로 된 전처리계를 먼저 처리하나 봅니다.
PWM_PORT_NUM 를 1로 변경하기 전에 먼저 묶어버리는 거지요

여기서 좌절하면 안되지요. 다음과 같이 하면 원하던대로 동작시킬 수 있습니다.


#define PWM_PORT_NUM 1

#define S3C2410_TCON_REGISTER(port_num,reg_name) \
S3C2410_TCON_T##port_num##reg_name

#define S3C2410_TCON_MANUALUPD(port_num) \
S3C2410_TCON_REGISTER(port_num,MANUALUPD)

PWM_PORT_NUM 를 변수로서 한번 더 전달하게 하는 거지요. 그럼 첫번째 전처리 과정에서 PWM_PORT_NUM 은 1로 치환되고 그 다음에 완성되어서 원하는 결과를 얻을 수 있습니다.

이제 깔끔하고 실수가 적은 소스코드가 완성되겠네요.

우훗~ '-'

'Programming > C Programming' 카테고리의 다른 글

해킹방지를 위한 코딩법  (0) 2010.08.20
__read_mostly keyword  (0) 2010.06.29
struct 변수 사용 bit 한계 설정하기  (0) 2009.12.02
[TIP] easy mistake casting buffer  (0) 2009.09.21
AtoH function  (0) 2009.09.11