• Tistory
    • 태그
    • 위치로그
    • 방명록
    • 관리자
    • 글쓰기
Carousel 01
Carousel 02
Previous Next

#define 에 관한 내용

Programming/C, C++, MFC 2013. 6. 7. 09:03




소스코드를 보다보면 

#ifndef XXX

#define XXX

~~~~~~~

#endif


이런 구문을 자주 봤는데 이게 어떤 의미인지 몰라 찾아봤다 


아래는 #define 전처리문에 관한 지식인에서 긁어온 내용이다. 정리가 잘 되어있는거 같다.


----------------------------------------------------------------------------------------


#define 이라는 구문은 컴파일러가 아닌 전처리기에 의해 처리되는 전처리기구문이라는 것을 아실 것입니다. (MS의 cl.exe 컴파일러는 전처리처리, 컴파일, 링킹 등을 모두 처리할 수 있기는 합니다만...)



기본적으로  define 구문의 기본 형태는 아래와 같습니다.
#define A B
'A를 B로 치환'하겠다는 의미라고 보시면 됩니다.

질문자는 B가 인자라고 생각하고 있는데, B는 인자가 아닙니다.
예를 들면,
#define max(a,b)            (((a) > (b)) ? (a) : (b))
와 같이 괄호가 나와야, a, b를 인자라고 볼 수 있는 것입니다.

#define 구문은 여러가지 기능이 있기 때문에 형태에 따라 다양하게 이용될 수 있습니다.
몇 가지 소개를 해드리는 선에서 마무리하겠습니다.

1. B 부분이 없다. (가드(guard)로 사용)
 - 질문자가 언급했던 sal.h를 열어보면 #define __ATTR_SAL 같은 구문이 있습니다.
 보통 #define TRUE 1 같은 구문과 달리 뭔가 대체하는 값이 없어보입니다.
이것은 전처리기에 정의(define)을 하되 특정한 값을 부여해주지 않은 형태라고 보시면 됩니다.

 - 활용예. 헤더파일 가드(여러 파일에서 include 되는 경우 중복 선언을 방지)를 위해 많이 사용됩니다.
 - 적용예. stdio.h를 열어보면 전체적으로 아래와 같은 구조로 되어 있을 것입니다.
#ifndef _INC_STDIO #define _INC_STDIO
... stdio.h의 내용
#endif  /* _INC_STDIO */
_INC_STDIO 라는 이름이 정의되어 있지 않으면 해당 블록(endif를 만날 때까지)의 내용을 유효하다고 보는 것이지요. 그런데 바로 아래 #define으로 해당 이름을 정의해서 한군데라도 먼저 포함하고 있으면 두번째는 include에서 무효화가 되는 것이지요.

A라는 헤더에서 stdio.h와 b.h를 포함하고 있다고 가정할 때, b.h 역시 stdio.h를 포함하고 있다고 하면 결국 A관점에서는 stdio.h가 두 번 하나의 헤더에 포함이 되게 되겠죠. 이런 경우가 흔히 발생되기 때문에 가드가 필요한 것입니다. 구글 역시 #define 가드를 스타일 가이드(클릭)에 포함하고 있습니다.

2. B부분이 하나(기본형태)
 - 위에서 설명한 형태라 넘어갑니다.

3. B부분이 여러개
 - 하나이나 여러개이나 별 차이는 없습니다.

#define A B
A를 B로 치환하겠다는 의미라고 보시면 됩니다.
질문자는 B가 인자라고 생각하고 있는데 보통 B를 인자라고 이야기하지 않습니다.

예를 들면,
소스코드 원문보기
  1. #define THAT +2 
  2. #define AND     +3 
  3. #define ETC     +5 
  4. #define THIS_IS   THAT AND ETC 
  5. int main() 
  6. { 
  7.    int i = THIS_IS; 
  8.    return 0; 
  9. } 

#define THIS_IS   THAT AND ETC 와 같은 부분이 있습니다만 결국은,,
전처리기에 의해 

소스코드 원문보기
  1. int main() 
  2. { 
  3.    int i = THAT AND ETC; 
  4.    return 0; 
  5. } 
로 바뀌고 다시,
소스코드 원문보기
  1. int main() 
  2. { 
  3.    int i = +2 +3 +5; 
  4.    return 0; 
  5. } 
의 형태가 되어버립니다. (최적화하는 컴파일러는 int i = 10; 이라는 상수로 만들 수 있습니다.)

Visual Studio의 경우 printf 함수의 선언 역시 SAL로 어노테이션되어 있습니다.
소스코드 원문보기
  1. _Check_return_opt_ _CRTIMP int __cdecl printf(_In_z_ _Printf_format_string_ const char * _Format, ...); 

[crtdefs.h]
#define _Check_return_opt_
#define _CRTIMP __declspec(dllimport)

[sal.h]
#define _In_z_                         _Pre_z_      _Deref_pre_readonly_
#define _Printf_format_string_ _Printf_format_string_impl_
#define _Pre_z_                          _Pre2_impl_(_$notnull,  _$zterm) _Deref_pre1_impl_(_$valid)
#define _Deref_pre_readonly_                   _Deref_pre1_impl_(_$readaccess)
#define _Printf_format_string_impl_   [SA_FormatString(Style="printf")]
#define _Pre2_impl_(p1,p2)                 [SA_Pre(p1,p2)]
#define _Deref_pre1_impl_(p1)              [SA_Pre(Deref=1,p1)]

결국 stdio.h에 선언된 최초 문장은 아래와 같이 바뀌고,,,
(_Check_return_opt_는 없어집니다)
소스코드 원문보기
  1. __declspec(dllimport) int __cdecl printf(_Pre_z_      _Deref_pre_readonly_ _Printf_format_string_impl_ const char * _Format, ...); 
위의 문장은 아래와 동일합니다.
소스코드 원문보기
  1. __declspec(dllimport) int __cdecl printf(_Pre2_impl_(_$notnull,  _$zterm) _Deref_pre1_impl_(_$valid)      _Deref_pre1_impl_(_$readaccess) [SA_FormatString(Style="printf")] const char * _Format, ...); 
소스코드 원문보기
  1. __declspec(dllimport) int __cdecl printf([SA_Pre(_$notnull,  _$zterm)] [SA_Pre(Deref=1,_$valid)]      [SA_Pre(Deref=1,_$readaccess)] [SA_FormatString(Style="printf")] const char * _Format, ...); 

이런 어노테이션(annotation) 문장들은 코드 분석 도구(code analysis tool)에 의해 읽혀져 컴파일시에 미리 유용하게 사용자에게 경고나 에러를 돌려줄 수 있게 해줍니다.

저작자표시 (새창열림)

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

Memory Leaks 어디서 누수가 일어나는지 잡아보자..  (0) 2013.07.01
CFileDialog 다중파일 선택하기  (0) 2013.06.14
MFC TabControl 사용법  (2) 2013.04.30
MFC Picture Control 에 BMP 파일 출력하기  (1) 2013.04.02
MFC 에서 wav 파일 재생하기  (1) 2013.04.02
블로그 이미지

매직블럭

작은 지식들 그리고 기억 한조각

,

카테고리

  • 살다보니.. (449)
    • 주절거림 (3)
    • 취미생활 (36)
      • 지식과 지혜 (3)
      • 풍경이 되어 (4)
      • Memories (17)
      • 엥겔지수를 높여라 (2)
    • mathematics (6)
      • Matrix Computation (2)
      • RandomProcesses (3)
    • English.. (8)
    • Programming (147)
      • C, C++, MFC (51)
      • C# (1)
      • OpenCV (17)
      • Python (58)
      • Git, Docker (3)
      • Matlab (4)
      • Windows (3)
      • Kinect V2 (2)
      • 기타 etc. (8)
    • 전공관련 (80)
      • Algorithm (6)
      • Deep Learning (54)
      • 실습 프로그램 (4)
      • 주워들은 용어정리 (8)
      • 기타 etc. (8)
    • Computer (118)
      • Utility (21)
      • Windows (31)
      • Mac (4)
      • Ubuntu, Linux (58)
      • NAS (2)
      • Embedded, Mobile (2)
    • IT, Device (41)
      • 제품 사용기, 개봉기 (14)
      • 스마트 체험단 신청 (27)
    • Wish List (3)
    • TISTORY TIP (5)
    • 미분류. 수정중 (1)

태그목록

  • 매트랩 함수
  • 에누리닷컴
  • DSLR
  • 일본
  • LIBSVM
  • 스마트체험단
  • 오봉자싸롱
  • matlab function
  • 매트랩
  • ColorMeRad
  • Computer Tip
  • SVM
  • 칼로리 대폭발
  • Deep Learning
  • 포르투갈
  • review
  • DeepLearning
  • portugal
  • 갤럭시노트3
  • 큐슈
  • CStdioFile
  • random variable
  • function
  • Convolutional Neural Networks
  • 후쿠오카
  • utility
  • ReadString
  • matlab
  • 크롬
  • 딥러닝

달력

«   2025/08   »
일 월 화 수 목 금 토
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
08-01 21:00

LATEST FROM OUR BLOG

RSS 구독하기

BLOG VISITORS

  • Total :
  • Today :
  • Yesterday :

Copyright © 2015 Socialdev. All Rights Reserved.

티스토리툴바