매크로는 C/C++의 매우 강력한 기능이며 기본적으로 모든 C 기능 ( )이 발로 지정되어 있습니다. 문에서 if
또는 EXIT_ON_FAILURE
를 확장하여 만든 if
에
if (doSomething())
EXIT_ON_FAILURE(s) /* <-- MISSING SEMICOLON! OH NOES!!! */
else
doSomethingElse();
는 else
이 속한 않습니다 매크로의 다음 사용을 고려? 어쨌든 하나의 누락 된 세미콜론의 동작은 전혀 예상치 못한 결과입니다. EXIT_ON_FAILURE() 이 함수 인 경우 컴파일러 오류가 발생합니다. 이 경우에는 컴파일하지만 잘못된 것을 수행하는 코드는 입니다.
매크로에 문제가 있습니다. 함수 또는 변수처럼 보이지만 은이 아닙니다. 잘못 쓰여진 매크로는 이주는 선물입니다. 매크로를 사용할 때마다 잠재적 인 미묘한 버그가 발생할 수 있으며 매크로를 변경할 때마다 논리 오류를 코드 에 건 드리면 사용자가 만지지 않았다고 위협 할 수 있습니다.
일반적으로 꼭 필요한 경우가 아니라면 매크로를 피해야합니다.
상수를 정의해야하는 경우 const
변수 또는 enum
을 사용하십시오. 좋은 컴파일러 (무료로 얻을 수 있음)는 #define 상수 처럼 결과 실행 파일에 리터럴로 바꿀 것입니다.하지만 예상대로 사용자 정의 변환을 처리하고 디버거에 이 표시됩니다 기호 테이블입니다.
인라인 함수와 같은 것이 필요한 경우 인라인 함수를 사용하십시오. C++과 C99 둘 다 제공하며 대부분 무료 컴파일러 (예 : 비어있는 컴파일러)는 오랫동안 확장자로 사용했습니다.
함수는 인수가 매크로 달리 평가 될, 그래서
#define DOUBLE(a) (a + a)
두 번 a
을 평가하는 반면
inline int DOUBLE(int a) {return a+a;}
은 오직 한 번 a
을 평가합니다 강제로. 즉, DOUBLE이 함수 인 경우보다 매크로 인 경우
x = DOUBLE(someVeryLongFunction());
이 두 배 오래 걸립니다.
DOUBLE(a << b)
이 완전히 놀라운 결과를 줄 것이다 :
또한, 나는 (의도적으로) 이 매크로 인수를 괄호로 깜빡 때문에. 은 즉
#define DOUBLE(a) ((a) + (a))
로 DOUBLE 매크로를 작성하는 기억해야 할 것입니다, 당신은 완벽 단지에 매크로를 작성 발에서 자신을 촬영 가능성을 최소화 할 필요가있다. 실수하면 실수로 을 지불하게됩니다.
모두 그렇습니다. 은입니다. 매크로를 사용하면 코드 이 더 읽기 쉽습니다. 그들은 거의없고 그 사이에 있지만 그들은 존재합니다. 그 중 하나는 코드가 다시 작성되는 assert
매크로입니다. 복잡한 시스템은 로컬 디버깅 방식으로 묶어 assert
-like 매크로 자신의 정의를 사용하는 것은 매우 흔한 일, 그 거의 항상, __FILE__
에서 __LINE__
및 조건의 텍스트를 얻기 위해 매크로로 구현된다.
는하지만 그렇다하더라도, 이것은 전형적인 assert
이 구현되는 방법이다 : 즉
#ifdef NDEBUG
# define assert(cond)
#else
# define assert(cond) __assert(cond, __FILE__, __LINE__, #cond)
#endif
은 함수와 같은 매크로는 함수 호출로 확장합니다. 이 방법을 사용하면 assert
을 호출 할 때 확장이 거의 비슷해 보이며 인수 확장이 과 같은 방식으로 이루어 지므로 확장이 여전히 매우 비슷합니다. .
그리고 몇 가지 다른 용도가 있습니다.기본적으로 언제든지 프로세스 자체에서 프로그램에 정보를 전달해야하므로 은 아마 매크로 시스템을 통과해야합니다. 그럼에도 불구하고 은 매크로에 닿는 코드의 양을 최소화해야하며 매크로의 영향을 최소화해야합니다.
마지막으로 한 가지. 코드가 더 빠를 것이라고 생각하여 매크로를 사용하고 싶다면 악마가 말하는 것을 알아야합니다. 에서 예전에는 작은 매크로를 매크로로 변환하면 눈에 띄게 성능이 향상되는 경우가있었습니다. 이 일 비록 :
대부분의 컴파일러는 인라인 기능을 지원합니다. 심지어 일부는 정적 함수에 을 자동으로 수행합니다.
현대 컴퓨터는 너무 빠르기 때문에 거의 기능을 호출하지 않는 오버 헤드가 있음을 거의 인식하지 못합니다.
인라인 함수 을하고하지 않는 컴파일러는 그냥 더 나은 하나 과로 교체 할 수없는 경우에만 당신은 오버 헤드를 호출 기능 입증은 병목 수 있습니다했습니다 당신은 아마 몇 가지 매크로 작성을 정당화 할 수 있습니다.
아마도.
나는 매크로를 사용하는 것이 대부분의 경우 좋지 않다고 생각한다. 세 번째 옵션이 더 좋습니다. –
'__LINE__'을 넘긴다면 함수로도 같은 일을 할 수 있습니다. – chris
@AdityaKumar : 세 번째 옵션을 제외하고는 유용한 행 번호가 제공되지 않습니다. 그것이 (때때로) 매크로를 사용하는 좋은 이유 중 하나입니다. –