πŸ“˜14μž₯ The Preprocessor | Study

파인·2022λ…„ 1μ›” 25일
0

C

λͺ©λ‘ 보기
4/9
post-thumbnail

C Programming, A Modern Approach - K.N.KING으둜 Cμ–Έμ–΄λ₯Ό κ³΅λΆ€ν•˜λ©΄μ„œ μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.
λ²ˆμ—­λ³Έ https://wikidocs.net/book/2494 을 μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.



14.1 How the Preprocessor Works
14.2 Preprocessing Directives
14.3 Macro Definitions
14.4 Conditional Compilation
14.5 Miscellaneous Directives


πŸ“ The Preproccessor

μ „μ²˜λ¦¬κΈ°λŠ” 컴파일 이전에 C ν”„λ‘œκ·Έλž¨μ„ μˆ˜μ •ν•΄μ£ΌλŠ” μ†Œν”„νŠΈμ›¨μ–΄μ΄λ‹€.



πŸ“ How the Preprocessor Works

μ „μ²˜λ¦¬κΈ°μ˜ 행동은 μ „μ²˜λ¦¬ μ§€μ‹œμž(preprocessing directives)에 μ˜ν•΄ μ œμ–΄λœλ‹€.
(μ „μ²˜λ¦¬ μ§€μ‹œμž : # 문자둜 μ‹œμž‘λ˜λŠ” λͺ…λ Ήμ–΄
ex. #define, #include)

#define μ§€μ‹œμžλŠ” 맀크둜(macro)λ₯Ό μ •μ˜ν•œλ‹€.
(맀크둜 : μƒμˆ˜, 자주 μ‚¬μš©ν•˜λŠ” ν‘œν˜„μ‹ 등을 μ˜λ―Έν•˜λŠ” 이름)

#include : νŠΉμ • νŒŒμΌμ„ μ—΄κ³ , κ·Έ λ‚΄μš©λ¬Όμ„ μ»΄νŒŒμΌν•  νŒŒμΌμ— μΆ”κ°€ν•œλ‹€.

μ•„λž˜ 그림은 컴파일 κ³Όμ •μ—μ„œ μ „μ²˜λ¦¬κΈ°μ˜ 역할을 보여쀀닀.

μ „μ²˜λ¦¬κΈ°λŠ” 주석은 띄어쓰기 문자 ν•˜λ‚˜λ‘œ λŒ€μ²΄ν•œλ‹€.

λŒ€λΆ€λΆ„μ˜ C μ»΄νŒŒμΌλŸ¬λŠ” μ „μ²˜λ¦¬κΈ°μ˜ 좜λ ₯물을 λ³Ό 수 있기 λ•Œλ¬Έμ— 였λ₯˜λ₯Ό 찾을 λ•Œ μœ μš©ν•˜λ‹€.



πŸ“ Preprocessing Directives

πŸ”Ž μ „μ²˜λ¦¬ μ§€μ‹œμžλ“€

1) 맀크둜 μ •μ˜(macro definition) : ex. #define으둜 맀크둜 μ •μ˜
2) 파일 μΆ”κ°€(file inclusion) : ex. #include둜 파일 μΆ”κ°€
3) 쑰건적 컴파일(conditional compilation) : ex. #if, #ifdef, ifndef, #elif, #else, #endif둜 μ½”λ“œμ˜ νŠΉμ • 뢀뢄을 μΆ”κ°€ν•˜κ±°λ‚˜ μ œμ™Έ

πŸ”Ž μ§€μ‹œμžλ“€μ˜ κ·œμΉ™

1) #으둜 μ‹œμž‘ν•œλ‹€.
2) μ§€μ‹œμžμ™€ 토큰 μ‚¬μ΄μ—λŠ” 띄어쓰기가 μž„μ˜μ˜ 개수만큼 λ“€μ–΄κ°ˆ 수 μžˆλ‹€.

#	define 		N 	(100) (o)

3) ν•˜λ‚˜μ˜ μ§€μ‹œμžμ—μ„œ λ‹€μŒμ€„λ‘œ λ„˜κΈ°λ €λ©΄ \둜 λλ‚˜μ•Ό ν•œλ‹€.

#define DISK_CAPACITY (SIDES *	\
		       TRACKS_PER_SIDE)

4) ν”„λ‘œκ·Έλž¨ μ–΄λ””μ„œλ“  λ“±μž₯ν•  수 μžˆλ‹€



πŸ“ Macro Definitions

λ§€ν¬λ‘œμ—λŠ” λ‹¨μˆœ(simple)맀크둜 뿐 μ•„λ‹ˆλΌ λ§€κ°œλ³€μˆ˜(parameterized)λ§€ν¬λ‘œλ„ μ‘΄μž¬ν•œλ‹€.

πŸ“ Simple Macros

πŸ”Ž simple macro (λ˜λŠ” object-like macro)

#define identifier replacement-list

μ „μ²˜λ¦¬κΈ°λŠ” μ‹λ³„μžκ°€ λŒ€μ²΄λͺ©λ‘μ„ μ˜λ―Έν•˜κ²Œ 됨을 ν‘œμ‹œ, νŒŒμΌμ— μ‹λ³„μžκ°€ λ“±μž₯ν•˜λ©΄ μ „μ²˜λ¦¬κΈ°λŠ” λŒ€μ²΄λͺ©λ‘μœΌλ‘œ λŒ€μ²΄ν•œλ‹€.

λ‹¨μˆœ λ§€ν¬λ‘œλŠ” κ³ μœ μƒμˆ˜λ₯Ό μ •μ˜ν•˜κΈ° μœ„ν•΄ 주둜 μ‚¬μš©λœλ‹€.

#define TRUE (1)
#define FALSE (0)
#define PI (3.14159)
#define MEM_ERR ("Error: not enough memory")

πŸ”Ž #define의 μž₯점

1) ν”„λ‘œκ·Έλž¨μ˜ 가독성, μˆ˜μ •μ„±μ„ λ†’μ—¬μ€€λ‹€.
2) 일관성 μ—†λŠ” μ½”λ“œλ‚˜ μ˜€νƒ€λ₯Ό 방지할 수 μžˆλ‹€.

  • #define의 좔가적인 μ‚¬μš©
    쑰건적 컴파일 μ œμ–΄ν•˜κΈ°. μ•„λž˜μ™€ 같은 μ½”λ“œλ‘œ 디버깅 κ΄€λ ¨ 좜λ ₯을 λ‹΄λ‹Ήν•˜λŠ” μ½”λ“œλ„ μΆ”κ°€μ μœΌλ‘œ 컴파일 ν•  수 있게 λ§Œλ“€ 수 μžˆλ‹€.
#define DEBUG 

Cμ—μ„œ 맀크둜λ₯Ό μƒμˆ˜μ²˜λŸΌ μ‚¬μš©ν•  땐 이름을 μ „λΆ€ λŒ€λ¬Έμžλ‘œ μž‘μ„±ν•˜λŠ” 것이 κ΄€μŠ΅μ΄λ‹€.



πŸ“ Parameterized Macros

πŸ”Ž parameterized macro (λ˜λŠ” function-like macro)

#define identifier( X1, X2, ..., Xn ) replacement-list

πŸ”Ž λ§€κ°œλ³€μˆ˜ 맀크둜(parameterized macro)의 이용

#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define IS_EVEN(n) ((n) % 2 == 0)

i = MAX(j+k, m-n);
if (IS_EVEN(i)) {
	++i;
}

μœ„μ˜ μ˜ˆμ‹œμ²˜λŸΌ λ§€κ°œλ³€μˆ˜ λ§€ν¬λ‘œλŠ” κ°„λ‹¨ν•œ ν•¨μˆ˜μ²˜λŸΌ μž‘λ™ν•˜κΈ°λ„ ν•œλ‹€.

μ’€ 더 μ˜ˆμ‹œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄,

#define TOUPPER(c) ('a' <= (c) && (c) <= 'Z' ? (c) - 'a' + 'A' : (c)) 

#define getchar() getc(stdin)

πŸ”Ž λ§€κ°œλ³€μˆ˜ 맀크둜(parameterized macro)의 μž₯점

1) ν”„λ‘œκ·Έλž¨μ΄ 쑰금 더 빨라진닀. ν•¨μˆ˜ ν˜ΈμΆœμ€ overheadλ₯Ό ν•„μš”λ‘œ ν•  수 μžˆλŠ”λ°, λ§€ν¬λ‘œλŠ” 그렇지 μ•Šλ‹€.
2) λ§€ν¬λ‘œλŠ” 일반적(generic)이닀. ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ™€ 달리 νŠΉμ •ν•œ ν˜•μ„ 가지고 μžˆμ§€ μ•Šλ‹€.

πŸ”Ž λ§€κ°œλ³€μˆ˜ 맀크둜(parameterized macro)의 단점
1) 컴파일된 μ½”λ“œκ°€ 길어진닀.
2) μž…λ ₯λ³€μˆ˜μ˜ ν˜•μ„ 확인해주지 μ•ŠλŠ”λ‹€.
3) 맀크둜λ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터λ₯Ό κ°€μ§ˆ 수 μ—†λ‹€. (ν•¨μˆ˜λŠ” ν•¨μˆ˜ 포인터가 쑴재)
4) λ§€ν¬λ‘œκ°€ μž…λ ₯λ³€μˆ˜λ₯Ό ν•œ 번 이상 평가할 수 μžˆλ‹€. (ν•¨μˆ˜λŠ” ν•œ 번만 평가)




πŸ“ The # Operator

#μ—°μ‚°μžλŠ” 맀크둜 μž…λ ₯λ³€μˆ˜λ₯Ό λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄λ‘œ μΉ˜ν™˜ν•œλ‹€.

πŸ”Ž # μ—°μ‚°μž μ‚¬μš©

#define PRINT_INT(n) printf(#n " = %d\n", n)

μ—μ„œ n λŒ€μ‹  λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄μ„ λ„£μ–΄μ€€λ‹€.

PRINT_INT(i/j);

λ”°λΌμ„œ μœ„ μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€.

printf("i/j=%d\n", i/j);



πŸ“ The ## Operator

##μ—°μ‚°μžλŠ” 두 토큰을 ν•˜λ‚˜μ˜ ν† ν°μœΌλ‘œ λΆ™μ—¬ μ€€λ‹€.

πŸ”Ž ## μ—°μ‚°μž μ‚¬μš©

#define MK_ID(n) i##n
int MK_ID(1);
int MK_ID(2);

와 같이 μž‘μ„±ν•΄μ£Όλ©΄ μ „μ²˜λ¦¬ μ΄ν›„μ—λŠ”

int i1; 
int i2;

κ°€ λœλ‹€.

max ν•¨μˆ˜μ˜ μ •μ˜λ₯Ό κ°–λŠ” 맀크둜λ₯Ό μž‘μ„±ν•˜λ©΄, 일일이 λ§Œλ“€μ§€ μ•Šκ³  μ—¬λŸ¬ ν˜•μ„ 받도둝 ν•  수 μžˆλ‹€.

맀크둜둜 두 개 μ΄μƒμ˜ maxν•¨μˆ˜λ₯Ό λ§Œλ“€ 수 μ—†λŠ”λ°, ##μ—°μ‚°μžλ‘œ 각 maxλ§ˆλ‹€ μ„œλ‘œ λ‹€λ₯Έ 이름을 λ§Œλ“€μ–΄ 해결해쀄 수 μžˆλ‹€.

#define GENERIC_MAX(type) type type##_max(type x, type y) { return x > y ? x : y; }

λ§Œμ•½ floatν˜• λ³€μˆ˜λ₯Ό μ‚¬μš©ν•œ maxν•¨μˆ˜κ°€ ν•„μš”ν•˜λ©΄ μ•„λž˜μ™€ 같이 μ •μ˜ν•  수 μžˆλ‹€.

GENERIC_MAX(float)

그럼 μ „μ²˜λ¦¬κΈ°μ— μ˜ν•΄ μ•„λž˜μ™€ 같이 바뀐닀

float float_max(float x, float y)
{
	return x > y ? x : y;
}



πŸ“ Generic Properties of Macro

πŸ”Ž λ§€ν¬λ‘œμ— μ μš©λ˜λŠ” κ·œμΉ™

1) 맀크둜 λŒ€μ²΄ λͺ©λ‘μ΄ λ‹€λ₯Έ 맀크둜의 λ°œλ™μ„ κ°–κ³  μžˆμ„ 수 μžˆλ‹€.

#define PI (3.14159)
#define TWO_PI (2 * PI)

2) μ „μ²˜λ¦¬κΈ°λŠ” μ‹λ³„μž, λ¬Έμžν˜• μƒμˆ˜, λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄μ˜ 일뢀인 맀크둜 이름을 λ¬΄μ‹œν•œλ‹€.

#define SIZE (256)
int BUFFER_SIZE;

μœ„ μ½”λ“œμ˜ 경우 BUFFER_SIZEλŠ” μ „μ²˜λ¦¬μ˜ 영ν–₯을 받지 μ•ŠλŠ”λ‹€.

3) 맀크둜의 μ •μ˜λŠ” 보톡 μ •μ˜λœ ν•΄λ‹Ή 파일 전체에 μ μš©λœλ‹€.

4) λ˜‘κ°™κ²Œ μž¬μ •μ˜λ₯Ό ν•˜μ§€ μ•ŠλŠ” 이상 μž¬μ •μ˜λŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.

5) #undef μ§€μ‹œμžμ— μ˜ν•΄ λ―Έμ •μ˜ 될 μˆ˜λ„ μžˆλ‹€.
μ•„λž˜μ½”λ“œλŠ” ν˜„μž¬ μ •μ˜λœ 맀크둜 N을 μ‚­μ œν•œλ‹€.

#undef N



πŸ“ Parentheses in Macro Definitions

λ§€ν¬λ‘œμ—λŠ” μ†Œκ΄„ν˜Έλ₯Ό 많이 μ¨μ£ΌλŠ”κ²ƒμ΄ μ’‹λ‹€.

1) λŒ€μ²΄λͺ©λ‘μ— μ—°μ‚°μžκ°€ ν¬ν•¨λ˜μ–΄ 있으면 λ°˜λ“œμ‹œ λŒ€μ²΄λͺ©λ‘μ„ μ†Œκ΄„ν˜Έλ‘œ 감싸주어야 ν•œλ‹€.

#define TWO_PI (2 * 3.14159)

2) λ§€ν¬λ‘œκ°€ λ§€κ°œλ³€μˆ˜κ°€ μžˆμ„ 경우 λ§€κ°œλ³€μˆ˜λ₯Ό λͺ¨λ‘ κ΄„ν˜Έλ‘œ 감싸주어야 ν•œλ‹€.

#define SCALE(x) ((x)) * 10)



πŸ“ Creating Longer Macros

μ‰Όν‘œλ₯Ό μ΄μš©ν•΄ λŒ€μ²΄λͺ©λ‘μ„ ν‘œν˜„μ‹μ˜ μ—°μ†μ²΄λ‘œ λ§Œλ“€ 수 μžˆλ‹€.

πŸ”Ž λ¬Έμžμ—΄μ„ 읽은 λ‹€μŒ 좜λ ₯을 ν•΄μ£ΌλŠ” 맀크둜 - (1)

#define ECHO(s) (gets(s), puts(s))

μ΄λ ‡κ²Œ ν•΄μ„œ ECHOλ₯Ό 마치 ν•¨μˆ˜μΈ κ²ƒμ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλ‹€.

ECHO(str); /* (gets(str), puts(str)); 이 λœλ‹€ */

κ·ΈλŸ¬λ‚˜ μ‰Όν‘œλ‘œλŠ” ν‘œν˜„μ‹μ΄ μ•„λ‹ˆλΌ ꡬ문을 μ—°κ²°μ‹œν‚¬ μˆ˜λŠ” μ—†λ‹€. ꡬ문을 μ—°κ²°μ‹œν‚€λ €λ©΄ do 루프λ₯Ό μ΄μš©ν•΄μ•Ό ν•œλ‹€.

πŸ”Ž λ¬Έμžμ—΄μ„ 읽은 λ‹€μŒ 좜λ ₯을 ν•΄μ£ΌλŠ” 맀크둜 - (2)


#define ECHO(s)				\
			do{		\
			gets(s);	\
			puts(s);	\
			} while (0)

μ„Έλ―Έμ½œλ‘ μ΄ μ—†λ‹€λŠ” 점을 λˆˆμ—¬κ²¨ 보자.

ECHOλ₯Ό μ‚¬μš©ν•  땐 λ°˜λ“œμ‹œ μ„Έλ―Έμ½œλ‘ μ„ μ΄μš©ν•΄ do문을 μ™„μ„±μ‹œμΌœμ£Όμ–΄μ•Ό ν•œλ‹€.

ECHO(str); /* do { gets(str); puts(str); } while (0); 이 λœλ‹€*/



πŸ“ Predefined Macros

πŸ”Ž Cμ—μ„œ μ‚¬μ „μ •μ˜λœ λ§€ν¬λ‘œλ“€

이름섀λͺ…
__LINE__μ»΄νŒŒμΌν•˜λŠ” 파일의 쀄 번호
__FILE__μ»΄νŒŒμΌν•˜λŠ” 파일 이름
__DATE__컴파일 λ‚ μ§œ ("Mmm dd yyyy"의 ν˜•μ‹)
__TIME__컴파일 μ‹œκ°„ ("hh:mm:ss"의 ν˜•μ‹)
__STDC__λ§Œμ•½ μ»΄νŒŒμΌλŸ¬κ°€ Cν‘œμ€€(C89 ν˜Ήμ€ C99)μΌμ‹œ 1μž„



πŸ“ Additional Predefined Macros in C99

πŸ”Ž Cμ—μ„œ μ‚¬μ „μ •μ˜λœ λ§€ν¬λ‘œλ“€

이름섀λͺ…
__STDC_HOSTED__호슀트 μ‹œν–‰μ΄λΌλ©΄ 1, 독립적이라면 0
__STDC_VERSION__μ§€μ›ν•˜λŠ” C의 ν‘œμ€€ 버전
__STDC__IEC 60559 κ³ μ •μ†Œμˆ˜μ  μ‚°μˆ μ„ 지원할 μ‹œ 1
__TIME__IEC 60559 λ³΅μ†Œμˆ˜ μ‚°μˆ μ„ 지원할 μ‹œ 1
__STDC__wchar_t의 값이 νŠΉμ • 년도와 월이 ISO 10646 ν‘œμ€€μ„ λ§Œμ‘±ν•  μ‹œ yyyymmL



πŸ“ Empty Macro Arguments

C99μ—μ„œλŠ” 맀크둜의 λͺ¨λ“  μž…λ ₯λ³€μˆ˜κ°€ λΉ„μ–΄μžˆμ„ 수 μžˆλ‹€. 이 경우 μ‰Όν‘œλ₯Ό μ΄μš©ν•˜μ—¬ μ–΄λ–€ μž…λ ₯λ³€μˆ˜κ°€ μƒλž΅λ˜μ—ˆλŠ”μ§€ ν‘œμ‹œν•œλ‹€.

#define ADD(x,y) (x+y)

μœ„μ™€ 같이 μ„ μ–Έν•œ 경우

i = ADD(, k); 

μœ„μ˜ ꡬ문은 λ‹€μŒκ³Ό κ°™λ‹€

i = ( + k); 

빈 μž…λ ₯λ³€μˆ˜κ°€ #의 ν”Όμ—°μ‚°μžμ˜ κ²½μš°μ—λŠ” ""(빈 λ¬Έμžμ—΄)이 λœλ‹€.

#define MK_STR(x) #x
...
char empty_string[] = MK_STR();

μœ„μ˜ ꡬ문은 μ „μ²˜λ¦¬κΈ°μ— μ˜ν•΄ μ•„λž˜μ™€ 같이 바뀐닀.

char empty_string[] = "";

빈 μž…λ ₯λ³€μˆ˜κ°€ ##의 ν”Όμ—°μ‚°μžμ˜ κ²½μš°μ—λŠ” μœ„μΉ˜ ν‘œμ‹œμž ν† ν°μœΌλ‘œ λŒ€μ²΄λ˜μ–΄ μ‘΄μž¬ν•˜λŠ” μž…λ ₯λ³€μˆ˜μ™€ λ§Œλ‚˜λ©΄ 사라진닀.

#define JOIN(x, y, z) x##y##z
...
int JOIN(a, b, c);
int JOIN(a, b, );
int JOIN(a, , c);
int JOIN(, , c);

μœ„μ˜ ꡬ문은 μ „μ²˜λ¦¬κΈ°μ— μ˜ν•΄ μ•„λž˜μ™€ 같이 바뀐닀.

int abc;
int ab;
int ac;
int c;



πŸ“ Macris with a Variable Number of Arguments (κ°€λ³€ 길이 μž…λ ₯λ³€μˆ˜ 맀크둜)

C99μ—μ„œλŠ” λ¬΄μ œν•œμ˜ μž…λ ₯λ³€μˆ˜λ₯Ό 받을 수 μžˆλ‹€. 이 κΈ°λŠ₯의 주된 λͺ©μ μ€ printfλ‚˜ scanf와 같이 κ°€λ³€ 길이 μž…λ ₯λ³€μˆ˜λ“€μ„ λ°›λŠ” ν•¨μˆ˜μ— μ‚¬μš©ν•΄μ£ΌκΈ° μœ„ν•΄μ„œ 이닀.

#define TEST(condition, ...) ((condition) ? \
	printf("Passed test: %s\n", #condition) : \
	printf(__VA_ARGS__))

... (μƒλž΅λΆ€ν˜Έ(ellipsis)) : 맀크둜의 λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ—μ„œ λ§ˆμ§€λ§‰μ— μœ„μΉ˜ν•˜λ©°, 일반적인 λ§€κ°œλ³€μˆ˜κ°€ μ‘΄μž¬ν•  μ‹œ μƒλž΅ λΆ€ν˜Έ 이전에 λ‚˜μ˜¨λ‹€

__VA_ARGS__ : κ°€λ³€ 길이 μž…λ ₯λ³€μˆ˜λ₯Ό κ°–λŠ” 맀크둜의 λŒ€μ²΄λͺ©λ‘μ—μ„œλ§Œ λ‚˜μ˜¬ 수 μžˆλŠ” νŠΉμˆ˜ν•œ μ‹λ³„μžμ΄λ‹€. μƒλž΅λΆ€ν˜Έμ— ν•΄λ‹Ήν•˜λŠ” λͺ¨λ“  μž…λ ₯λ³€μˆ˜λ₯Ό μ˜λ―Έν•œλ‹€

TEST : μ΅œμ†Œν•œ 두 개의 μž…λ ₯λ³€μˆ˜λ₯Ό ν•„μš”λ‘œ ν•œλ‹€.
첫번재 μž…λ ₯λ³€μˆ˜λŠ” condition λ§€κ°œλ³€μˆ˜μ— λŒ€μ‘ν•˜κ³ , λ‚˜λ¨Έμ§€ μž…λ ₯λ³€μˆ˜λ“€μ€ μƒλž΅ λΆ€ν˜Έμ— λŒ€μ‘ν•œλ‹€.

πŸ”Ž TEST 맀크둜의 μ‹€μ œ μš©λ²•

TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage);

λ§Œμ•½ voltage <= max_voltage라면
Passed test : voltage <= max_voltageλ₯Ό 좜λ ₯,
voltage > max_voltage 라면
Voltage 125 exceeds 120 을 좜λ ₯ν•  것이닀.




πŸ“ The __func__ Identifier

__func__ μ‹λ³„μžλŠ” ν˜„μž¬ μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜μ˜ 이름을 μ €μž₯ν•˜κ³  μžˆλŠ” λ¬Έμžμ—΄ λ³€μˆ˜μ²˜λŸΌ ν–‰λ™ν•œλ‹€.

static const char \__func__[] = "function-name";

μ΄λŸ¬ν•œ μ‹λ³„μžκ°€ μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— λ‹€μŒκ³Ό 같은 디버깅 맀크둜λ₯Ό μž‘μ„±ν•΄μ€„ 수 μžˆλ‹€.

#define FUNCTION_CALLED() printf("%sκ°€ 호좜됨\n", __func__);
#define FUNCTION_RETURNS() printf("%sκ°€ λ°˜ν™˜ν•¨\n", __func__);

void f(void)
{
	FUNCTION_CALLED(); /* "fκ°€ 호좜됨"을 좜λ ₯함 */
	FUNCTION_RETURNS(); /* "fκ°€ λ°˜ν™˜ν•¨"을 좜λ ₯함 */
}



πŸ“ Conditional Compilation

πŸ“ The #if and #endif Directives

#if - #endif 짝을 μ΄μš©ν•˜λ©΄ μ½”λ“œμƒμ—μ„œλŠ” λ‚¨μ•„μžˆλ”λΌλ„ 상황에 따라 컴파일 ν•˜μ§€ μ•Šμ„ 수 μžˆλ‹€.

μ•„λž˜ μ½”λ“œμ˜ 경우 DEBUG 값이 1μ΄λ―€λ‘œ μ‹€ν–‰λ˜λ©°, DEBUG값을 0으둜 λ°”κΎΈλ©΄ μ»΄νŒŒμΌλ˜μ§€ μ•ŠλŠ”λ‹€.

#define DEBUG 1

#if DEBUG
printf("i의 κ°’ : %d\n", i);
printf("j의 κ°’ : %d\n", j);
#endif 



#### πŸ“ The defined Operator

ν•΄λ‹Ή μ‹λ³„μžκ°€ μ •μ˜λœ 맀크둜일 경우 definedλŠ” κ°’ 1을 내보내고, μ•„λ‹ˆλΌλ©΄ 0을 내보낸닀.
즉 ν•΄λ‹Ή μ‹λ³„μžκ°€ λ§€ν¬λ‘œλ‘œμ„œ μ •μ˜λ˜μ—ˆλŠ”μ§€λ₯Ό νŒλ‹¨ν•˜λŠ” μ—°μ‚°μžμ΄λ‹€.

#if define(DEBUG)
…
#endif

λ§Œμ•½ DEBUGκ°€ λ§€ν¬λ‘œλ‘œμ„œ μ •μ˜κ°€ λ˜μ–΄μžˆλ‹€λ©΄ #if ~ #endif 사이 문이 μ‹€ν–‰λœλ‹€.




πŸ“ The #ifdef and #ifndef Directives

#ifdef μ§€μ‹œμžλŠ” μ‹λ³„μžκ°€ ν˜„μž¬ 맀크둜둜 μ •μ˜λ˜μ–΄μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•œλ‹€.

#ifdef identifier
...
#endif

μ‹λ³„μžκ°€ μ •μ˜λ˜μ–΄ μžˆλ‹€λ©΄ #ifdef ~ #endif 사이 문이 μ‹€ν–‰λœλ‹€. μ΄λŠ” μ•žμ„œ λ³Έ #if와 defined μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄μ„œλ„ ν•  수 μžˆλ‹€.

#ifndefλŠ” #ifdefμ™€λŠ” λ°˜λŒ€λ‘œ μ‹λ³„μžκ°€ ν˜„μž¬ λ§€ν¬λ‘œμ— μ •μ˜λ˜μ–΄μžˆμ§€ μ•Šμ•˜λŠ”μ§€μ˜ μ—¬λΆ€λ₯Ό ν™•μΈν•œλ‹€.




πŸ“ The #elif and #else Directives

#if, #ifdef, #ifndef λ“±κ³Ό λ”λΆˆμ–΄ #elif, #elseλ₯Ό μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ 쑰건듀을 νŒλ³„ν•΄μ€„ 수 μžˆλ‹€.




πŸ“ Use of Conditional Compilation

πŸ”Ž μ—¬λŸ¬ κΈ°κ³„λ‚˜ μš΄μ˜μ²΄μ œμ™€ ν˜Έν™˜μ΄ λ˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•  λ•Œ

#if defined(WIN32)
…
#elif defined(MAC_OS)
…
#elif defined(LINUX)
…
#endif

이λ₯Ό μ΄μš©ν•΄μ„œ μ–΄λŠ μš΄μ˜μ²΄μ œμ—μ„œ λŒμ•„κ°€λŠ”μ§€ ν‘œμ‹œλ₯Ό 해쀄 수 μžˆλ‹€.

πŸ”Ž λ‹€μ–‘ν•œ μ»΄νŒŒμΌλŸ¬μ—μ„œ μ»΄νŒŒμΌν•  수 μžˆλŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•  λ•Œ

μ„œλ‘œ λ‹€λ₯Έ μ»΄νŒŒμΌλŸ¬λ“€μ€ μ„œλ‘œ λ‹€λ₯Έ C버전을 μΈμ‹ν• μˆ˜ 있기 λ•Œλ¬Έμ— 였래된 μ»΄νŒŒμΌμ„ μ‚¬μš©ν•΄μ•Ό ν•  λ•ŒλŠ” __STDC__ 맀크둜 등을 μ΄μš©ν•΄μ•Ό ν•œλ‹€.

#if __STDC__
Function prototypes
#else
Old-style function declarations
#endif

πŸ”Ž λ§€ν¬λ‘œμ— κΈ°λ³Έ μ •μ˜λ₯Ό 내렀쀄 λ•Œ

쑰건뢀 μ»΄νŒŒμΌμ€ λ§€ν¬λ‘œκ°€ ν˜„μž¬ μ •μ˜λ˜μ—ˆλŠ”μ§€λ₯Ό νŒλ‹¨ν•˜κ³  그에 λ”°λ₯Έ 행동을 해쀄 수 μžˆλ‹€. μ•„λž˜ μ½”λ“œλŠ” BUFFER_SIZEκ°€ μ •μ˜λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ μ •μ˜λ₯Ό ν•œλ‹€.

#ifndef BUFFER_SIZE
#define BUFFER_SIZE 256
#endif

πŸ”Ž μΌμ‹œμ μœΌλ‘œ 주석을 ν¬ν•¨ν•œ μ½”λ“œλ₯Ό 없앨 λ•Œ

#if 0
Lines containing comments 
#endif



πŸ“ Miscellaneous Directives

#error, #line, #pragma μ§€μ‹œμž

πŸ“ The #error Directive

#error message

μ „μ²˜λ¦¬κΈ°λŠ” #error μ§€μ‹œμžλ₯Ό λ§Œλ‚˜λ©΄ messageλ₯Ό λ°˜λ“œμ‹œ ν¬ν•¨ν•˜λŠ” 였λ₯˜ 문ꡬλ₯Ό 좜λ ₯ν•œλ‹€. 였λ₯˜ 문ꡬ의 μ •ν™•ν•œ μ„œμ‹μ€ μ»΄νŒŒμΌλŸ¬λ§ˆλ‹€ λ‹€λ₯΄λ‹€.

πŸ”Ž #error μ‚¬μš© μ˜ˆμ‹œ

#if defined(WIN32)
…
#elif defined(MAC_OS)
…
#elif defined(LINUX)
…
#else
#error νŠΉμ •λœ μš΄μ˜μ²΄μ œκ°€ μ—†μŠ΅λ‹ˆλ‹€
#endif



πŸ“ The #line Directive

#line μ§€μ‹œμžλŠ” ν”„λ‘œκ·Έλž¨μ˜ 쀄에 번호λ₯Ό λΆ€μ—¬ν•˜λŠ” 법을 λ°”κΏ€ λ•Œ μ‚¬μš©ν•œλ‹€. λ˜ν•œ μ»΄νŒŒμΌλŸ¬κ°€ λ‹€λ₯Έ μ΄λ¦„μ˜ νŒŒμΌμ„ 읽고 μžˆλ„λ‘ μ°©κ°ν•˜κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

#line은 두 가지 μ„œμ‹μ„ κ°–λŠ”λ‹€.

1) #line μ§€μ‹œμž (1번 μ„œμ‹)
#line n

이 μ§€μ‹œμžλŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ λ‹€μŒ 쀄듀이 n, n+1, n+2 순으둜 λ²ˆν˜Έκ°€ λ³€ν•˜κ²Œ λ§Œλ“ λ‹€.

2) #line μ§€μ‹œμž (2번 μ„œμ‹)
#line n "file"

μ§€μ‹œμž 이후에 λ‚˜μ˜¨ 쀄듀은 "file"(파일λͺ…)을 κ°–λŠ” νŒŒμΌμ—μ„œ 온 κ²ƒμœΌλ‘œ μ·¨κΈ‰ν•œλ‹€.

πŸ”Ž #line μ‚¬μš© μ˜ˆμ‹œ

#line 10 "bar.c"

μ»΄νŒŒμΌλŸ¬κ°€ foo.c의 5번 μ€„μ—μ„œ 였λ₯˜λ₯Ό νƒμ§€ν•œ 경우 였λ₯˜ λ¬Έκ΅¬λŠ” foo.c파일의 5번째 쀄이 μ•„λ‹Œ bar.c 파일의 13번째 μ€„μ—μ„œ 였λ₯˜κ°€ 났닀고 μΈμ‹ν•œλ‹€.

13번째 쀄인 μ΄μœ λŠ” μ§€μ‹œμžκ°€ foo.c의 1번 쀄을 μ°¨μ§€ν•˜μ—¬ foo.cκ°€ 2번 쀄뢀터 μ‹œμž‘ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

#line μ§€μ‹œμžλŠ” 주둜 C μ½”λ“œλ₯Ό 좜λ ₯ν•΄μ£ΌλŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ μ‚¬μš©ν•œλ‹€. 제일 λŒ€ν‘œμ μΈ μ˜ˆμ‹œλ‘œλŠ” yacc(컴파일러의 컴파일러)κ°€ μžˆλ‹€.




πŸ“ The #pragma Directive

#pragma μ§€μ‹œμžλŠ” μ»΄νŒŒμΌλŸ¬κ°€ νŠΉμ • 행동을 ν•˜λ„λ‘ λΆ€νƒν•˜κ²Œ λ§Œλ“œλŠ” 방법이닀.

πŸ“ The _Pragma Directive

C99λŠ” #pragma μ§€μ‹œμžμ™€ μ„žμ–΄ μ“Έ 수 μžˆλŠ” _Pragma μ—°μ‚°μžλ₯Ό μ œκ³΅ν•œλ‹€.


profile
κ³΅λΆ€μ •λ¦¬μš©

0개의 λŒ“κΈ€