PRE-00 함수형의 매크로보다는 인라인이나 정적 함수를 사용하라
일반 함수는 함수 호출의 오버헤드가 존재한다. 때문에 간단한 코드에 대한 함수 호출은 성능 상의
이슈가 발생할 수 있다. 그래서 전통적인 프로그래머들은 간단한 코드에 대해 일반 함수가 아닌
함수형 매크로를 사용하기도 한다. 그러나 매크로는 컴파일러에 의한 평가가 아닌 단순 치환
구조이기 때문에 부수 효과가 발생할 수 있다.
인라인 함수란 함수 호출 코드가 함수의 기계어 코드로 치환되는 함수를 의미한다. 인라인 함수는
컴파일 타임에 처리되므로 함수 호출의 오버헤드가 없어진다. 그러므로 함수형 매크로보다는
인라인 함수를 사용하는 것이 좋다.
위험한 코드 1
- 매크로 함수 호출 시 사용된 인자에 대한 증가, 감소, 메모리 변수 접근 등은 부수 효과를 발생시킬 수 있다.
- 해결 방법 - 인라인 함수를 사용하여 해결할 수 있다.
위험한 코드 2
- 다음의 코드는 매크로를 사용해 전역 카운터를 증가시키는 코드이다.
하지만 매크로가 치환되면서 지역 카운터를 증가시키고 있다.
- 해결 방법 - 인라인 함수를 사용한다. 인라인 함수는 함수 구현부가 컴파일될 때 식별자를 전역 변수로 처리한다.
PRE-01 매크로에서는 매개 변수에 괄호를 사용하라
부수 효과를 줄이려면 반드시 매개 변수에 괄호를 사용해야 한다.
위험한 코드
- 아래의 함수형 매크로는 괄호를 사용하지 않아 문제가 된다.
- 해결 방법 - 매크로의 모든 매개변수에 괄호를 사용하면 된다.
PRE-02 매크로로 치환될 영역은 반드시 괄호로 둘러싸야 한다
매크로로 치환될 영역을 괄호로 둘러싸면 근처의 표현식으로 인해 우선순위가 바뀌는 일을 방지할 수 있다.
위엄한 코드1
- 의도하지 않은 결과과 나오게 된다.
- 해결 방법 - 매크로로 치환될 영역을 괄호로 둘러싼다
위험한 코드2
- 치환된 코드가 수식으로 평가되어 정상적으로 동작하지 않는다.
- 해결 방법 - 치환될 영역은 반드시 괄호로 둘러싸거나 열거 타입의 상수로 치환한다.
PRE-03 타입 인코딩 시 매크로 정의 대신 타입 정의를 사용하라
타입 정의는 스코프(scope) 규칙이 적용되는 반면 매크로 정의는 적용되지 않는다.
위험한 코드
- 아래의 코드에서 name은 포인터로 선언되었지만 tel은 포인터로 선언되어 있지 않다.
#include <stdio.h>
#define cstring char *
int main(){
cstring name, tel;
name = "Michael";
tel = "010-0000-0000"
printf("name: %s, tel: %s\n", name, tel);
return 0;
}
- 해결 방법 - 타입 정의를 사용한다.
typedef char * cstring;
int main(){
cstring name, tel;
name = "Michael";
tel = "010-0000-0000"
printf("name: %s, tel: %s\n", name, tel);
return 0;
}
PRE-04 토큰들을 연결하거나 문자열 변환을 할 때 매크로 치환을 고려하라
매크로 연산자
- ## - 매크로가 치환되는 과정에서 두 개의 토큰을 하나로 병합(concatencation)
- # - # 연산자 다음에 있는 토큰을 문자열화
위험한 코드
- 아래의 코드는 줄 번호가 의도한대로 출력되지 않는다.
- 해결 방법 - 매크로 인자를 치환한 다음에 문자열로 만들려면 두 단계의 매크로를 사용해야 한다.
PRE-05 헤더 파일에 항상 인클루드 가드를 둬라
소프트웨어 개발 프로젝트에서 헤더 파일의 중복으로 인한 문제가 일어나기 쉽다.
때문에 헤더파일을 설계할 때는 반드시 인클루드 가드(Include guard)를 사용해야 한다.
위험한 코드
- 다음 코드는 헤더 파일의 중복으로 인한 문제가 발생할 수 있다.
- 해결 방법 - 인클루드 가드를 적용한다.
PRE-06 복수 구문 매크로를 do-while 루프로 감싸라
여러 실행문을 그룹으로 만들어 연속적으로 실행하는 경우, 구문상 루프로 묶어줘야만 나중에 매크로가 if처럼
한개의 실행문이나 중괄호로 묶인 실행 단위를 처리하는 부분에서 사용될 때 안전하게 작동한다.
위험한 코드
- 다음은 복수 구문으로 정의된 함수형 매크로를 사용할 경우, 의도하지 않은 결과를 초래한다.
- 해결 방법 - do-while 루프로 감싼다.
PRE-07 절대로 불안전한 매크로를 할당, 증가, 감소, 메모리 변수 접근, 함수 호출과 함께 사용하지 마라
함수형 매크로에서 사용된 매개 변수에 대하여 증가 또는 감소 등의 연산은 부수 효과(side effect)를 발생시킬 수 있으므로
사용하면 안된다.
위험한 코드
- 다음의 코드는 의도하지 않은 결과를 초래한다.
- 해결 방법 1. - 매개 변수에 대하여 증가 또는 감소를 수행하지 않는다.
#incldue <stdio.h>
- 해결 방법 2. - 함수의 이름에 안전하지 않음을 알린다.
- 해결 방법 3. - 인라인 함수로 정의한다.
'Software' 카테고리의 다른 글
Secure Cordng C - Expression (0) | 2018.08.30 |
---|---|
Secure Cordng C - Declaration (0) | 2018.07.24 |
Secure Cordng C - Coding Style (0) | 2018.07.20 |
Secure Cordng C - 포인터의 개념과 이해 #3 (0) | 2018.07.18 |
Secure Cordng C - 포인터의 개념과 이해 #2 (0) | 2018.07.18 |