상세 컨텐츠

본문 제목

PRE01-C. 매크로에서는 매개변수에 괄호를 사용하라

개발 환경/CERT - 취약점

by cepiloth 2021. 6. 1. 14:38

본문

728x90
반응형

매크로 정의의 모든 매개변수 이름에 괄호를 사용하라.

 

부적절한 코드 예

아래 CUBE()는 매개변수 이름에 괄호를 사용하지 않아 문제가 된다.

#define CUBE(I) (I * I * I)

그 결과 다음과 같은 호출은,
int a = 81 / CUBE(2 + 1);

아래처럼 치환되어 의도한 것과 다른 결과가 된다.
int a = 81 / (2 + 1 * 2 + 1 * 2 + 1); /* 11이 된다.*/

 

해결 방법

CUBE() 매크로의 모든 매개변수 이름에 괄호를 사용해 정확하게 치환되도록 하면 된다.

#define CUBE(I) ( (I) * (I) * (I) )
int a = 81 / CUBE(2 + 1)

 

예외

PRE01-EX1 : 치환되는 부분의 매개변수 이름들이 콤마로 구분되는 경우에는 실제 인자가 복잡하더라도 매크로 매개변수에 괄호를 해줄 필요가 없다. 콤마가 연산자 중 우선순위가 가장 낮아서, 다른 방식으로 인자가 파싱될 수 없기 때문이다. 함수의 인자를 구별하는 콤마 역시 우선순위가 가장 낮다. 여기서 언급하는 콤마 구분자는 콤마 연산자와 다르다.

#define FOO(a, b, c) bar(a, b, c)
/* ... */
FOO(arg1, arg2, arg3);

 

PRE01-EX2 : 매크로의 매개변수들을 ## 연산자를 사용해 병합하는 경우 혹은 # 연산자로 문자열처럼 쓰거나 인접한 문자열을 병합하는 경우에는 각 매개변수에 대해 괄호를 적용할 수 없다. 아래 JOIN() 매크로는 새로운 토큰을 만들기 위해 두 매개변수를 병합한다. SHOW() 매크로는 인자 한 개를 문자열로 바꾸어 printf()의 포맷 안에 넣고 있다.

#define JOIN(a, b) (a ## b)
#define SHOW(a) printf("#a = %d\n", a)

 

728x90
반응형

관련글 더보기

댓글 영역