본문 바로가기

C언어/시큐어코딩

[PRE00-C] ~ [PRE10-C]

C 언어에서 매크로를 사용할 때 발생할 수 있는 보안 및 유지보수 문제를 방지하기 위한 코딩 가이드로 11개가 있다

 

1. PRE00-C: 함수형 매크로보다는 인라인 함수나 정적 함수를 사용하라

매크로 대신 inline 또는 static 함수를 사용하면 디버깅이 용이하고 타입 안정성 유지됨

//잘못된 예제 (매크로 사용)
#define SQUARE(x) (x * x)

//개선된 예제 (인라인 함수 사용)
static inline int square(int x) {
    return x * x;
}

 

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

연산자 우선순위 문제를 방지하기 위해 매개변수를 항상 괄호로 감싸야 함

//잘못된 예제
#define MULTIPLY(a, b) a * b

//개선된 예제
#define MULTIPLY(a, b) ((a) * (b))
int result = MULTIPLY(2 + 3, 4);     //(2+3)*4 = 20

 

3. PRE02-C: 매크로로 치환될 영역은 반드시 괄호로 둘러싸야 한다

매크로 치환 결과가 예기치 않게 동작하지 않도록 주의

//잘못된 예제
#define ADD(a, b) a + b

//개선된 예제
#define ADD(a, b) ((a) + (b))
int x = ADD(2, 3) * 4;  //20이 나와야 하지만 잘못된 매크로는 2 + 3 * 4 = 14가 됨
//치환할떄는 그대로 치환하고 처리할떄는 괄호안의 처리후 다음 처리

 

4. PRE03-C: 타입 인코딩 시 매크로 정의 대신 타입 정의를 사용하라

매크로 대신 typedef나 enum을 사용하는 것이 더 안전

//잘못된 예제
#define BYTE unsigned char
//개선된 예제
typedef unsigned char BYTE;

 

5. PRE04-C: 표준 헤더 파일 이름을 재사용하지 마라

표준 라이브러리 이름을 재사용하면 충돌이 발생할 수 있음

//잘못된 예제
//"stdio.h"를 다른 의미로 정의하면 문제가 발생함
#define stdio_h "my_stdio.h"

 

6. PRE05-C: 토큰들을 연결하거나 문자열 변환을 할 때 매크로 치환을 고려하라

#define CONCAT(a, b) a##b
#define TO_STRING(x) #x

int CONCAT(my, Var) = 10;  // myVar = 10;
char *str = TO_STRING(Hello);  // "Hello"

 

7. PRE06-C: 헤더 파일에 항상 인클루전 가드를 둬라

중복 포함을 방지하려면 #ifndef 가드를 사용

//my_header.h
#ifndef MY_HEADER_H
#define MY_HEADER_H

void myFunction();

#endif // MY_HEADER_H

인클루전 가드란

 

8. PRE07-C: 연속되는 물음표를 사용하지 마라

C에서는 ??= 같은 3개 연속 물음표가 일부 환경에서 예기치 않게 작동할 수 있음

// printf("??!");  // 일부 환경에서는 문제가 발생할 수 있음

 

9. PRE08-C: 중복된 헤더 파일 이름이 없는지가 보장돼야 한다

헤더 파일이 충돌하지 않도록 네이밍 컨벤션을 명확해야한다.

//프로젝트 내 헤더 파일이 모두 고유한지 확인
#include "projectA_util.h"
#include "projectB_util.h"

 

10. PRE09-C: 안전한 함수를 덜 안전한 함수로 바꾸지 마라

strcpy() 같은 위험한 함수를 안전한 strncpy()로 대체

//잘못된 예제
char dest[10];
strcpy(dest, "This is too long!");  //버퍼 오버플로우 위험

//개선된 예제
strncpy(dest, "Hello", sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';  //null-terminator 추가

 

11. PRE10-C: 복수 구문 매크로를 do-while 루프로 감싸라

여러 줄 매크로를 사용할 때 do { ... } while (0); 패턴을 사용하면 예기치 않은 동작을 방지 가능

 

//잘못된 예제
#define INCREMENT(x) x++; x++;

//개선된 예제
#define INCREMENT(x) do { x++; x++; } while (0)

int num = 5;
INCREMENT(num);  //안전하게 동작함

'C언어 > 시큐어코딩' 카테고리의 다른 글

매크로 함수 VS 인라인 함수  (0) 2025.03.13
시큐어코딩을 위한 C언어 기본 용어  (0) 2025.03.11