답변:
전 처리기 매크로는 코드에 적용된 대체 패턴 일뿐입니다. 컴파일이 시작되기 전에 확장으로 대체되기 때문에 코드의 거의 모든 곳에서 사용할 수 있습니다.
인라인 함수는 본문이 호출 사이트에 직접 삽입되는 실제 함수입니다. 함수 호출이 적절한 경우에만 사용할 수 있습니다.
이제 함수와 같은 컨텍스트에서 매크로 대 인라인 함수를 사용하는 한 다음 사항에 유의하십시오.
첫째, 전 처리기 매크로는 컴파일 전 코드에서 "복사 붙여 넣기"입니다. 따라서 유형 검사 가 없으며 일부 부작용 이 나타날 수 있습니다.
예를 들어 두 값을 비교하려는 경우 :
#define max(a,b) ((a<b)?b:a)
max(a++,b++)
예를 들어 사용하면 부작용이 나타납니다 ( a
또는 b
두 번 증가합니다). 대신 (예 :)
inline int max( int a, int b) { return ((a<b)?b:a); }
max(fibonacci(100), factorial(10000))
. 더 큰 작업 은 두 번 계산됩니다. (
Inline 함수는 컴파일러에 의해 확장되며, 매크로는 전처리기에 의해 확장되며 이는 단순한 텍스트 대체입니다.
함수 호출 중에 유형 검사가 수행되는 동안 매크로 호출 중에 유형 검사가 없습니다.
인수 및 작업 순서의 재평가로 인해 매크로 확장 중에 원하지 않는 결과와 비 효율성이 발생할 수 있습니다. 예를 들면
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int i = 5, j = MAX(i++, 0);
결과적으로
int i = 5, j = ((i++)>(0) ? (i++) : (0));
매크로 인수는 매크로 확장 전에 평가되지 않습니다.
#define MUL(a, b) a*b
int main()
{
// The macro is expended as 2 + 3 * 3 + 5, not as 5*8
printf("%d", MUL(2+3, 3+5));
return 0;
}
// Output: 16`
return 키워드는 함수의 경우처럼 값을 반환하기 위해 매크로에서 사용할 수 없습니다.
인라인 함수는 오버로드 될 수 있습니다.
매크로에 전달 된 토큰은 Token-Pasting operator라는 연산자 ##을 사용하여 연결할 수 있습니다.
매크로는 일반적으로 인라인 함수를 사용하여 함수 호출 (서브 루틴으로의 점프 방지) 중에 시간 오버 헤드 (초과 시간)를 제거하는 코드 재사용에 사용됩니다.
이미 주어진 것들에 또 다른 차이점을 추가하려면 #define
디버거에서 단계를 수행 할 수 없지만 인라인 함수를 통해 단계를 수행 할 수 있습니다.
매크로는 네임 스페이스를 무시합니다. 그리고 그것은 그들을 사악하게 만듭니다.
인라인 함수는 매크로와 유사합니다 (함수 코드는 컴파일 타임에 호출 지점에서 확장되기 때문). 인라인 함수는 컴파일러에 의해 구문 분석되는 반면 매크로는 전처리기에 의해 확장됩니다. 결과적으로 몇 가지 중요한 차이점이 있습니다.
경우에 따라 매크로에 인수로 전달 된 식을 두 번 이상 평가할 수 있습니다. http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx
매크로는 사전 컴파일 시간에 확장되므로 디버깅에 사용할 수 없지만 인라인 함수를 사용할 수 있습니다.
- 좋은 기사 : http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1
;
매크로 함수와 인라인 함수 의 차이점을 알기 위해서는 먼저 그것들이 정확히 무엇인지, 언제 사용해야하는지 알아야합니다.
기능 :
int Square(int x){
return(x*X);
}
int main()
{
int value = 5;
int result = Square(value);
cout << result << endl;
}
함수 호출에는 관련된 오버 헤드가 있습니다. 함수가 실행을 마친 후 반환해야하는 위치를 알아야하고 값을 스택 메모리에 저장해야하기 때문입니다.
작은 응용 프로그램의 경우 문제가되지 않지만 매초 수천 건의 트랜잭션이 발생하는 금융 응용 프로그램의 예를 들어 보겠습니다. 우리는 함수 호출을 사용할 수 없습니다.
매크로 :
# define Square(x) x*x;
int main()
{
int value = 5;
int result = Square(value);
cout << result << endl;
}
int 결과 = Square (x * x)
그러나 매크로에는 이와 관련된 버그가 있습니다.
#define Square(x) x*x
int main() {
int val = 5;
int result = Square(val + 1);
cout << result << endl;
return 0;
}
여기서 출력은 36 이 아니라 11 입니다.
인라인 기능 :
inline int Square(int x) {
return x * x;
}
int main() {
using namespace std;
int val = 5;
int result = Square(val + 1);
cout << result << endl;
return 0;
}
출력 36
Inline 키워드는 컴파일러에게 함수 호출을 함수 본문으로 대체하도록 요청합니다. 여기서는 먼저 표현식을 평가 한 다음 전달하기 때문에 출력이 정확합니다. 반환 주소 및 스택을 저장할 필요가 없으므로 함수 호출 오버 헤드를 줄입니다. 함수 인수에는 메모리가 필요하지 않습니다.
매크로와 인라인 함수 비교 :
결론:
인라인 함수는 성능을 향상시키고 사용하기에 안전하고 함수 호출 오버 헤드도 줄이므로 매크로보다 때때로 더 유용합니다. 컴파일러에 대한 요청 일 뿐이며 특정 함수는 다음과 같이 인라인되지 않습니다.
그것은 좋은 일입니다. 왜냐하면 그것은 컴파일러가 다른 방식으로 일을하는 것이 최선이라고 생각할 때입니다.
GCC (다른 사람에 대해서는 잘 모르겠습니다)에서 함수를 인라인으로 선언하는 것은 컴파일러에 대한 힌트 일뿐입니다. 함수가 호출 될 때마다 함수 본문을 포함할지 여부를 결정하는 것은 하루가 끝날 때 컴파일러가 결정합니다.
인라인 함수와 전 처리기 매크로의 차이는 비교적 큽니다. 전 처리기 매크로는 하루가 끝날 때 텍스트를 대체하는 것입니다. 컴파일러가 인수 및 반환 유형에 대한 유형 검사를 수행 할 수있는 많은 기능을 포기합니다. 인수의 평가는 매우 다릅니다 (함수에 전달하는 표현식에 부작용이있는 경우 디버깅 시간이 매우 즐거워집니다). 함수와 매크로를 사용할 수있는 위치에는 미묘한 차이가 있습니다. 예를 들어 다음과 같은 경우 :
#define MACRO_FUNC(X) ...
MACRO_FUNC는 분명히 함수의 본문을 정의합니다. 함수를 사용할 수있는 모든 경우에 올바르게 실행되도록 특별한주의가 필요합니다. 예를 들어 잘못 작성된 MACRO_FUNC는 오류를 일으킬 수 있습니다.
if(MACRO_FUNC(y)) {
...body
}
정상적인 기능을 아무 문제없이 사용할 수 있습니다.
인라인 함수는 반복적이거나 반복적 인 명령문이있는 경우 함수 호출로 작동하여 명령의 반복 실행을 방지합니다. 프로그램의 전체 메모리를 절약하는 데 매우 유용합니다.
#include<iostream>
using namespace std;
#define NUMBER 10 //macros are preprocessed while functions are not.
int number()
{
return 10;
}
/*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases.
However, this is not the case with functions.
Also, macros do not check for compilation error (if any). Consider:- */
#define CUBE(b) b*b*b
int cube(int a)
{
return a*a*a;
}
int main()
{
cout<<NUMBER<<endl<<number()<<endl;
cout<<CUBE(1+3); //Unexpected output 10
cout<<endl<<cube(1+3);// As expected 64
return 0;
}
매크로는 실제 함수 호출 오버 헤드를 포함하지 않으므로 일반적으로 함수보다 빠릅니다.
매크로의 몇 가지 단점 : 타입 검사가없고 간단한 교체를 유발하므로 디버그하기 어려움 매크로에는 네임 스페이스가 없으므로 코드의 한 섹션에있는 매크로가 다른 섹션에 영향을 미칠 수 있습니다. 매크로는 위의 CUBE () 예제와 같이 부작용을 일으킬 수 있습니다.
매크로는 일반적으로 하나의 라이너입니다. 그러나 한 줄 이상으로 구성 될 수 있으며 함수에는 이러한 제약이 없습니다.
#define TWO_N(n) 2 << n
다음과 cout << CUBE(TWO_N(3 + 1)) << endl;
? (그것은과 출력의 라인을 종료하는 것이 좋습니다 endl
그것을 시작하는 것보다 있습니다.)