1 / 88

선언과초기화 (DCL)

선언과초기화 (DCL). 사이버보안학과 김현성. 제안. DCL00-C 변하지 않는 객체는 const 로 보장해둬라 DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 DCL02-C 시각적으로 구별되는 식별자를 사용하라 DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 DCL04-C 한 번에 여러 변수를 선언하지 마라 DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라

Télécharger la présentation

선언과초기화 (DCL)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 선언과초기화(DCL) 사이버보안학과 김현성

  2. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  3. 제안 • DCL10-C 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 • DCL11-C 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 • DCL12-C 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 • DCL13-C 함수에 의해 바뀌지 않을 값에 대한 포인터를 함수의 매개변수로 사용할 때는 const로정의하라 • DCL14-C 여러 컴파일 단위를 거치는 전역 변수 초기화의 순서에 대해서는 어떤 가정도 하지 마라 • DCL15-C 현재 범위를 넘어서까지 사용되지 않을 객체는 static으로 선언하라

  4. 규칙 • DCL30-C 객체를선언할 때 적절한 지속공간을 지정하라 • DCL31-C 식별자를 사용하기 전에 먼저 선언하라 • DCL32-C 서로에게 보이는 식별자가 유일한지를 보장하라 • DCL33-C 함수 인자에서 restrict로 지정된소스 포인터와 목적 포인터가 동일한 객체를 참조하지 않게 하라 • DCL34-C 캐시될 수 없는 데이터에는 volatile을 사용하라 • DCL35-C 함수 정의와 맞지 않는 타입으로 함수를 변환하지 마라 • DCL36-C 링크 분류에서 충돌되는 식별자를 선언하지 마라

  5. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  6. 변하지않는 객체는 const로보장해둬라 DCL00-C 부적절한 코드 예 float pi = 3.14159f; float degrees; float radians; /* ... */ radians = degrees * pi / 180; => pi=3.14159f; => pi가 수정되지 못하도록 보호되어야함

  7. 변하지않는 객체는 const로보장해둬라 DCL00-C 해결방법 const float pi = 3.14159f; float degrees; float radians; /* ... */ radians = degrees * pi / 180;

  8. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  9. 내부 스코프에서 변수 이름을 재사용하지 마라 개념적 변수 스코프룰 • 전역변수가 사용될 수 있는 범위 내에서 어떤 변수든 중복해서 전역 변수 이름을 사용하면 안된다 • 어떤 블록 안에서 이미 사용되고 있는 변수와 동일한 이름으로 다른 블록에서 선언하면 안된다

  10. 내부 스코프에서 변수 이름을 재사용하지 마라 DCL01-C 부적절한코드 예 char msg[100]; charmsg[100]; void report_error(const char *error_msg){ char msg[80]; /* ... */ strncpy(msg, error_msg, sizeof(msg)); return; } int main(void){ char error_msg[80]; /* ... */ report_error(error_msg); /* ... */ } char msg[80]; strncpy(msg, error_msg, sizeof(msg)); => 의도하지 않은값이 복사됨, 버퍼오버플로우

  11. 내부 스코프에서 변수 이름을 재사용하지 마라 DCL01-C 해결방법 charsystem_msg[100]; void report_error(const char *error_msg){ char default_msg[80]; /* ... */ if (error_msg) strncpy(system_msg, error_msg, sizeof(system_msg)); else strncpy(system_msg, default_msg, sizeof(system_msg)); return; } int main(void){ char error_msg[80]; /* ... */ report_error(error_msg); /* ... */ }

  12. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  13. 시각적으로 구별되는 식별자를 사용하라 비슷해보이는 식별자 • 1(하나)과 l(소문자엘) • 0(영)과 O(대문자 O) • 2(둘)와 Z(대문자 Z) • 5(다섯)와 S(대문자 S) • 8(여덟)과 B(대문자 B)

  14. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  15. 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 어썰션(assert) • assert()는 소프트웨어 결점을 찾아 제거하는데 사용되는 진단도구 • If(index<0||index>=size) { printf(“배열 인덱스 범위 오류”); } • assert(index>=0&&index<size); • assert()는 인자값이 0이면 메시지 출력 • assert((index>=0&&index<size)&&”배열 인덱스 범위 오류”);

  16. 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 DCL03-C 부적절한코드 예 structtimer{ unit8_t MODE; unit32_t DATA; unit32_t COUNT; }; int func(void) { assert(offsetof(timer, DATA)==4); } <= offsetof(n,a) n구조체의 a멤버의 바이트 반환 => func()가 호출되어야만 assert실행됨

  17. 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 DCL03-C 해결방법 structtimer{ unit8_t MODE; unit32_t DATA; unit32_t COUNT; }; #if(assert(offsetof(timer, DATA) !=4)) #error “DATA must be at offset 4” #endif => error지시자 사용시 컴파일타임에 어썰션 평가

  18. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  19. 한 번에 여러 변수를 선언하지 마라 DCL04-C 부적절한코드 예 char *src = 0, c = 0; => char*src, char *c => char *src, char c

  20. 한 번에 여러 변수를 선언하지 마라 DCL04-C 해결방법 char *src; char *c; => 개별 행으로 변수를 선언

  21. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  22. 코드의 가독성을 높이기 위해 타입 정의를 사용하라 DCL05-C 부적절한코드 예 void (*signal(int, void(*) (int))) (int); => signal() 함수 선언은 이해하기 힘듦

  23. 코드의 가독성을 높이기 위해 타입 정의를 사용하라 DCL05-C 해결방법 typedefvoid (*SighandlerType) (int signum); extern SighandlerType signal( int signum, SighandlerType handler ); <= extern 다른소스코드 .c에서 변수나 함수를 현재파일에서 접근하거나 호출할 때 사용

  24. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  25. 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 상수 • 정수형 상수 • 10 • 0x1C • 부동소수점 상수 • 1.0 • 6.022e+23 • 문자상수 • ‘a’ • ‘\x10’ • 문자리터럴 • “hello, world” • “\n” <= 심볼릭 상수를 통해 적절한 이름을 붙여 코드의 명확성을 제시하는게 좋음 <= const or 열거형 상수 or 객체형 매크로

  26. 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 상수 지정 • const • const unsigned int buffer_size = 256; • 컴파일타임에 정수형 상수가 필요할 때 사용 불가 • 열거형 상수 • enum { max = 15 }; int a[max]; • 객체형매크로 • #define buffer_size 256

  27. 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 DCL06-C 부적절한코드 예 /* ... */ if(age >= 18){ /* 작업진행 */ } else{ /* 다른작업 진행 */ } /* ... */ 18 => 정수 리터럴 18의 의미가 모호함

  28. 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 DCL06-C 해결방법 enum{ ADULT_AGE=18 }; /* ... */ if(age >= ADULT_AGE){ /* 작업진행 */ } else{ /* 다른작업 진행 */ } /* ... */

  29. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  30. 함수 선언 시 적절한 타입 정보를 포함시켜라 DCL07-C 부적절한코드 예 int max(a, b) int a, b; { return a>b ? a : b; } => 매개변수와 변수 선언을 별개로 가짐

  31. 함수 선언 시 적절한 타입 정보를 포함시켜라 DCL07-C 해결방법 int max(int a, int b) { return a>b ? a : b; }

  32. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  33. 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 DCL08-C 부적절한코드 예 코드에서 OUT_STR_LEN이 항상 IN_STR_LEN 보다 두개 커야 하는 관계 enum { IN_STR_LEN=18, OUT_STR_LEN=20 };

  34. 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 DCL08-C 해결방법 enum { IN_STR_LEN=18, OUT_STR_LEN=IN_STR_LEN+2 };

  35. 제안 • DCL00-C 변하지않는 객체는 const로보장해둬라 • DCL01-C 내부 스코프에서 변수 이름을 재사용하지 마라 • DCL02-C 시각적으로 구별되는 식별자를 사용하라 • DCL03-C 상수 수식의 값을 테스트할 때 정적 어썰션을 사용하라 • DCL04-C 한 번에 여러 변수를 선언하지 마라 • DCL05-C 코드의 가독성을 높이기 위해 타입 정의를 사용하라 • DCL06-C 프로그램 로직상의 고정적인 값을 나타낼 때는 의미 있는 심볼릭 상수를 사용하라 • DCL07-C 함수 선언 시 적절한 타입 정보를 포함시켜라 • DCL08-C 상수 정의에서는 상수 간의 관계가 적절하게 나타나도록 정의하라 • DCL09-C errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라

  36. errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라 에러코드함수 반환 타입 • errno를 반환하는 많은 함수가 반환 타입을 int로 선언하거나에러 상태 값을 반환 • errno_t 타입은 errno에서 찾을 수 있는 값들을 갖고 있는 객체의 타입으로 사용되어야 함 errno: 0 message: Successerrno: 1 message: Operation not permittederrno: 2 message: No such file or directoryerrno: 3 message: No such processerrno: 4 message: Interrupted system callerrno: 5 message: Input/output errorerrno: 6 message: No such device or address…errno: 125 message: Operation canceled

  37. errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라 DCL09-C 부적절한코드 예 int enum { NO_FILE_POS_VALUES = 3 }; int operator(FILE *file,int *width,int *height,int *data_offset) { int file_w; int file_h; int file_o; fpos_t offset; if(file==NULL) {return EINVAL;} errno=0; if(fgetpos(file, &offset)!=0) {return errno;} if(fscanf(file, “%i %i %i”, &file_w, &file_h, &file_o) != NO_FILE_POS_VALUES){ return EIO; } … => 반환형 int not errno_t형 EINVAL errno EIO

  38. errno 에러코드를 반환하는 함수의 반환 타입을 errno_t로 정의하라 DCL09-C 해결방법 #include <errno.h> enum { NO_FILE_POS_VALUES = 3 }; errno_t operator(FILE *file,int *width,int *height,int *data_offset) { int file_w; int file_h; int file_o; fpos_t offset; if(file==NULL) {return EINVAL;} errno=0; if(fgetpos(file, &offset)!=0) {return errno;} if(fscanf(file, “%i %i %i”, &file_w, &file_h, &file_o) != NO_FILE_POS_VALUES){ return EIO; } …

  39. 제안 • DCL10-C 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 • DCL11-C 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 • DCL12-C 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 • DCL13-C 함수에 의해 바뀌지 않을 값에 대한 포인터를 함수의 매개변수로 사용할 때는 const로정의하라 • DCL14-C 여러 컴파일 단위를 거치는 전역 변수 초기화의 순서에 대해서는 어떤 가정도 하지 마라 • DCL15-C 현재 범위를 넘어서까지 사용되지 않을 객체는 static으로 선언하라

  40. 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 가변인자 함수 va_list • 원래 C 함수들은 고정된 개수의 인수들을 취함. '가변인자 함수'는 함수가 호출 될 때 마다 인수의 개수를 변경 가능 • 가변인자 함수를 사용하기 위해서는 'stdarg.h' 헤더 파일이 필요 • va_list 형으로 선언 • va_start를 사용해서 va_list 형의 포인터 변수를 인수로써 초기화 • va_arg를 호출함으로써 가변인수들을 엑세스  • va_end를 호출해서 포인터 변수인 인수를 끝냈음을 알림

  41. 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 DCL10-C 부적절한코드 예 => 호출 average(1, 3, 6, 4, 1); enum { va_eol = -1 }; unsigned int average(int first, …){ unsigned int count = 0; unsigned int sum = 0; int i = first; va_list args; va_start(args, first); while(i != va_eol){ sum += i; count++; i = va_arg(args, int); } va_end(args); return(count ? (sum / count) : 0); } => 종료값 -1 을 만날 수 없어 스택 에서 값을 계속 이용

  42. 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 DCL10-C 해결방법 enum { va_eol = -1 }; unsigned int average(int first, …){ unsigned int count = 0; unsigned int sum = 0; int i = first; va_list args; va_start(args, first); while(i != va_eol){ sum += I; count++; i = va_arg(args, int); } va_end(args); return(count ? (sum / count) : 0); } => 호출시 average(1, 3, 6, 4, 1, -1);

  43. 제안 • DCL10-C 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 • DCL11-C 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 • DCL12-C 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 • DCL13-C 함수에 의해 바뀌지 않을 값에 대한 포인터를 함수의 매개변수로 사용할 때는 const로정의하라 • DCL14-C 여러 컴파일 단위를 거치는 전역 변수 초기화의 순서에 대해서는 어떤 가정도 하지 마라 • DCL15-C 현재 범위를 넘어서까지 사용되지 않을 객체는 static으로 선언하라

  44. 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 가변인자 함수 • 가변 인자 함수의 인자 • 정수형 인자의 경우 int보다 작은 타입의 인자는 int로 승계되고, 그렇지 않은 경우는 unsigned int(4)로 승계됨 • float 타입의 인자는 double(8)로 승계됨

  45. 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 DCL11-C 부적절한코드 예 constchar *error_msg=“Error occurred”; /* ... */ printf(“%s:%d”, 15, error_msg); => 인자의 순서 불일치 오류 => printf()함수는 가변인자 함수로 구현 15: Error occurred

  46. 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 DCL11-C 해결방법 constchar *error_msg=“Error occurred”; /* ... */ printf(“%d:%s”, 15, error_msg);

  47. 제안 • DCL10-C 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 • DCL11-C 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 • DCL12-C 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 • DCL13-C 함수에 의해 바뀌지 않을 값에 대한 포인터를 함수의 매개변수로 사용할 때는 const로정의하라 • DCL14-C 여러 컴파일 단위를 거치는 전역 변수 초기화의 순서에 대해서는 어떤 가정도 하지 마라 • DCL15-C 현재 범위를 넘어서까지 사용되지 않을 객체는 static으로 선언하라

  48. 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 DCL12-C 부적절한코드 예 => string_mx는 CERT라이브러리 string_m.h에 정의(사용자에게 멤버노출) 정보은닉,데이터캡슐화 제공불가 struct string_mx{ size_t size; size_t maxsize; unsigned char strtype; char *cstr; } typedef struct string_mx * string_m; /*함수선언*/ extern errno_t strcpy_m(string_m s1, const string_m s2); extern errno_t strcat_m(string_m s1, const string_m s2); /*기타*/

  49. 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 DCL12-C 해결방법 • string_mx의 데이터 타입이 외부에서 보이지 않도록 private으로 재구현 => 두개의 헤더파일 생성 (하나는 외부노출, 하나는 관리용 내부 파일) • 외부노출 파일(string_mx 구조체는 내부파일에 제시) struct string_mx; typedef struct string_mx *string_m;

  50. 제안 • DCL10-C 가변 인자를 가진 함수에서는 함수 작성자와 함수 사용자 간의 약속이 지켜져야 한다 • DCL11-C 가변 인자 함수와 연관된 타입 문제를 파악하고 있어야 한다 • DCL12-C 불투명한 타입을 사용해 추상 데이터 타입을 구현하라 • DCL13-C 함수에 의해 바뀌지 않을 값에 대한 포인터를 함수의 매개변수로 사용할 때는 const로정의하라 • DCL14-C 여러 컴파일 단위를 거치는 전역 변수 초기화의 순서에 대해서는 어떤 가정도 하지 마라 • DCL15-C 현재 범위를 넘어서까지 사용되지 않을 객체는 static으로 선언하라

More Related