접두어: Macro
거대한 이라는 의미를 나타내는 접두어로 아주 작은 이란 뜻의 접두어 Micro와는 비교된다.
최근에는 매크로가 "전체" 마이크로가 "개별"이라는 의미가 됨.
본래 매크로라는 개념 자체는 프로그래밍 언어의 기능에서 처음 등장함
C/C++ 등, 매크로를 지원하는 언어에서 약식 문법을 정의하면
컴파일러가 컴파일을 하기 전에 약식 문법으로 정의된 코드를 원래 코드로 변환을 한후 컴파일 한다.
이 기능이 처음 도입된 Lisp에서는 이 원래 코드로 변환하는 키워드를 원래 크게 확장한다는 의미에서
macroexpand라고 불렀고, 이 확장 규칙을 macro라고 부르는데 이후의 언어들에서도
이 용어로 굳어지게 되었다.
C/C++ 에서의 매크로는 어떤 키워드를 코드로 치환하는 것이 기본으로,
인수를 받던지 코드를 문자열로 받던지 이름을 바꾸는 정도의 기능을 제공한다.
사실 C/C++ 의 매크로는 매크로 기능을 탑재하고 있는 다른 언어들에 비해 기능이 빈약한 편이다.
현존 언어들 중 탑급 매크로를 탑재하고 있는 Lisp의 경우 아예 언어를 재창조하는 수준의
매크로도 작성이 가능하다.
매크로의 주된 용도는 상수 정의, 인라이닝, 문법 정의/변형 등이 있다.
상수 정의나 인라이닝의 경우 컴파일러가 잘 최적화하지 못하는 경우에도 강제로 치환해버릴 수 있다.
다만 최근에는 매크로를 지양하는 분위기가 짙다.
상수의 정의는 언어차원에서 제공되는 경우가 많으며, 인라이닝도 컴파일러가 거의 모든 경우에
적절히 해주기 때문에 문법 변형의 경우 장점도 있고 다른 방식으로 대체하기도 힘들지만
애초에 문법을 변형하는 순간 다른 사람이 코드를 이해하고 수정하기 힘들기 때문에
처음부터 변형할 필요도 없을 정도로 간결하고 적절한 문법을 제공하려 하는 추세다.
추가로 타입 안정성, 문법 같은 중요한 오류 점검도 매크로에는 기대하기 힘들며,
네임스페이스 같은 기능을 완전히 무시해버리고 정말 찾기 힘든 잘못된 식을 만들어 내는 경우가 있다.
C++ 기준으로 매크로 상수는 enum hack, constexpr을,
매크로 함수는 (템플릿)(constexpr)함수를 대신 사용하는 것이 바람직하다.
#include <stdio.h>
#define PI 3.14
/* Using Preprocessor(Macro) */
//#define SQUARE(X, Y) ((X)*(Y))
//#define CIRCLE_AREA(R) (SQUARE((R), (R))* PI)
/* Using Compiler(Function) */
double Square(double x, double y)
{
return x * y;
}
double CircleArea(double r)
{
return Square((r), (r)) * PI;
}
int main(void)
{
double radius = 2.1;
//printf("radius = %.2lf, Circle Area = %lf", radius, CIRCLE_AREA(radius));
printf("Circle Area = %.2lf", CircleArea(radius));
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ADD 1
#define SUB 0
int main(void)
{
int num1;
int num2;
printf("Type in two integer\n");
scanf_s("%d %d", &num1, &num2);
#if ADD
printf("%d + %d = %d \n", num1, num2, num1 + num2);
#endif
#if SUB
printf("%d - %d = %d \n", num1, num2, num1 - num2);
#endif
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//#define ADD 1
#define SUB 0
int main(void)
{
int num1;
int num2;
printf("Type in two integer\n");
scanf_s("%d %d", &num1, &num2);
#ifdef ADD
printf("%d + %d = %d \n", num1, num2, num1 + num2);
#endif
#ifdef SUB
printf("%d - %d = %d \n", num1, num2, num1 - num2);
#endif
return 0;
}
'Language > C & C++' 카테고리의 다른 글
[C++] Related to Inline (0) | 2022.10.17 |
---|---|
[C++] Related to Reference (0) | 2022.10.17 |
Exception handling (0) | 2022.10.14 |
Implement reference-based call-by-reference (0) | 2022.09.28 |
l-value and r-value (0) | 2022.09.27 |