2010-01-18 2 views
6

나는 단점이 같은 방법으로 전처리를 사용하는 무엇인지 알고 싶습니다 :전 처리기를 사용하여 함수 호출을 정의하는 단점은 무엇입니까?

#define SOME_FUNCTION someFunction(someArgument) 

는 기본적으로 나는이 느낌은 (안 가장 좋은 방법은 확실히 나) 잘못된 -하지만 난 이유를 모르겠어요 ... 내 전처리 기술은 녹슨 것입니다.

void myfunc() { 
    DO_STEP_ONE; 
    THEN_ANOTHER_STEP; 
    KEEP_GOING; 
    LAST_STEP; 
} 

하지만 일반적으로 그냥 열심히 코드를 읽고 이해할 수 있습니다 :

답변

0

는이보다 읽기 쉬운 방식으로 프로세스 단계를 정의하기위한 매우 폐쇄 된 영역에서 가끔 유용하다.

코드의 독자가 그 정의가 무엇을 의미하는지 자세히 알지 못하는 경우가 아니라면 어떤 종류의 단축키 일지라도 사람들이 두 줄을보고 코드 줄을 이해하게됩니다 (맨 위 파일과 함수로).

나는 이런 종류의 접근법을 거의 사용하지 않습니다. 언어, 컴파일러, 등, 등, 등에 따라 달라집니다

+0

매크로를 사용하면 같은 이름의 함수를 사용하는 것보다 읽기 쉽지 않습니다 – user463035818

0

...

그러나, 이름은 그 지침은 이전에 컴파일하는 과정을 발생 암시 한 번, 그것은 아무 문제가 없습니다.

프리 프로세서 다른 의해 해결 될 수있는 컴퓨터 과학에서의 실제 값으로 모든 상수 참조하므로 모든 적절한 코드와 유사 기능, ...

0

모든 문제를 제거 간접 수준

:-) 이러한 추가 간접 수준 중 하나는 어떤 점에서 그 함수가 다른 인수가 필요하거나 필요하지 않은 것을 말 전화를 걸려면 함수가 호출되는 모든 위치를 변경하는 대신 #define을 한 번 변경하면됩니다.

개발에 유용하지만 프로덕션 코드를 유지하는 것은 위험합니다 ... 성숙한 코드를 가지고 있으면이 규칙을 대체하기 위해 전 처리기를 실행하고 변경하지 않아도된다는 것을 알고 있습니다.

+0

간접 지정 수준이 너무 높으면 어떨까요? ;) – daotoad

5

단점? 보통 매크로 정의는 실행 파일의 심볼 테이블에서 끝나지 않습니다. 조금 더 디버깅하기가 어렵습니다. 확실히 표현은 corectly 평가

#define MIN(A,B) ((A) < (B))?(A):(B); 

공지 사항 난 '(' ')이'하기 위해 모든 인수를 마무리해야한다 :

5

문제는 인수가 = 다시 사용될 때마다 평가된다는 것입니다 . 그러나 우리가 이것을한다면 어떻게 될까요?

int s = MIN(++current,Max); 

이 코드는 함수가 호출되기 전에 현재 값이 한 번 증가한다고 예상합니다.그것은 시험에 한 번 증가 매크로와 두 번째이기 때문에 그러나 최대

에 비해 여전히 작은 경우
+0

이것은 실제로 매크로의 단점이지만'gcc'는 다음을 회피하기위한 * 컴파일러 관련 * 확장을 제공합니다 :'#define MIN (a, b) ({typeof (a) _a = (a); typeof (b) _b = (b); _a <_b? _a : _b;})'. – kennytm

+0

@Kenny : 매크로 Foo가 내 것보다 낫다. 나는 그것을 시도하고 그것을 작동합니다. 비록 그것이 그렇게 보이지는 않았지만 나는 성명 (Block)이 가치로 작용할 수 있다고 생각하지 않았다. –

+0

@Kenny : 안타깝게도'_a'와'_b'라고 불리는 변수에 대해'MIN '이 호출되면 gcc의 확장 기능이 작동하지 않을 것입니다. – jamesdlin

2

당신이 생각할 수있는 몇 가지 문제가 있습니다

매크로 ++ C에서
  • 더 네임 스페이스가 없습니다은 그리고 클래스 범위, 그래서 그것은 어디서나 동일합니다. 이에 대한 예는 불행한 min과 max가 windows.h의 어딘가에 정의되어 있다는 것입니다. windows 용 프로그래밍 중이고 windows.h를 포함하고 std :: numeric_limits :: max()를 쓰고 싶다면 max가 약간의 코드로 대체 될 것입니다 ... 이것은 전처리 기가 실행 된 후에 호환되지 않는 코드를 남깁니다. (좋아, windows.h에서 min/max 매크로를 끄는 방법이 있지만 여전히 열악한 디자인입니다!)
  • 매크로를 디버깅 할 수 없습니다. 디버거가 매크로 안의 코드에서 매크로가 사용되는 줄에서 멈 춥니 다.
  • 매크로 매개 변수의 재평가가 가능합니다 (매크로 내부에 로컬 변수가있는 블록을 만들면 디버깅을 할 수 있습니다. 심지어 더 나쁜!)
0

왜 특정 전 처리기 코드를 사용하는 데 불리한 점이 있습니까? 조건부 컴파일 (포함 가드 포함) 이외의 작업에 전처리 기 매크로를 사용하면 자동으로 잘못된 것으로 간주됩니다. 올바른 질문은 특정 용도에 이점이 있는지 여부입니다.

전 처리기 매크로는 어떤 식 으로든 범위 나 사용법을 존중하지 않습니다. 예상치 못한 어려운 방법으로 완벽하게 좋은 코드를 망칠 수 있습니다. 당신이 그것을 사용해야 할 특별한 이유가 없다면 항상 그것을 피하십시오. 당신이 작업을 수행해야합니다 (그리고 어떤 경우 때 수도가) 잘 경우

1

는, 당신은 적어도 "기능 같은"따라서 같은 매크로를 정의해야합니다 :

#define SOME_FUNCTION() someFunction(defaultArgument) 

그렇지 않으면 당신이 쓰는 것 코드가 실제로 함수 호출 일 때 상수에 의한 대입처럼 보입니다. 즉;

x = SOME_FUNCTION ; // hidden function call 

하지만 당신이 작성하는 의무 것 "기능 같은"매크로

:

x = SOME_FUNCTION() ; // shorthand function-call with default argument 

어떤 언어 구문을 사용하여 더 나은 일치 전처리 구문.

일반적으로 기능과 유사한 매크로는 피하는 것이 가장 좋지만, 일부는 다른 것보다 더 교활합니다. 최악의 경우는 아닙니다. 그러나 C 나 C++에서 함수 래퍼를 쉽게 작성할 수 있으며 대부분의 경우 기본 인수를 사용하는 것이 좋습니다.

0

단점은 코드를 숨기는 것입니다. 코드를 숨기는 것이 좋습니다.

아래쪽은 일반적으로 위쪽보다 크다.

보통이 특별한 방법은 거의 쓸모가 및 호출이 더 좋아

someModule-> someStorage-> functionList [storage.getFunctionName] .pointer-> 된 SomeFuncion (... 똑같이 모호한 인수를 보인다 않는 ...);

이렇게하는 것이 중요하지 않습니다. 인수 만 모호한 호출 인 경우 인수 만 줄입니다. 함수 만있는 경우에는 함수 만 축약하십시오.두 경우 함수가 무엇으로 호출되지 않은 경우, 당신은 당신이 인수 목록에서 제거하고 함수 본문 내에서 취득하는 것이 좋습니다,

SOME_FUNCTION(SOME_ARGUMENT); 

더 나을 수 있습니다. 쌍이 자주 반복되는 경우 작은 변형으로 래퍼 기능을 고려할 수 있습니다.

매크로 코드에서 몇 가지 버그를 만든 후에는 디버깅하는 것이 쉽지 않을 것이며 경솔하게 사용하지 않을 것입니다.

관련 문제